使用Java NIO进行网络编程,看下服务端的例子

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; public class Server {
private static int PORT = 8000;
private static final long PAUSE_BETWEEEN_MSGS = 10; // millisecs
private static ByteBuffer echoBuffer = ByteBuffer.allocate(4);
private static ByteBuffer sendBuffer = ByteBuffer.allocate(256);
private static ConcurrentHashMap<Integer, SocketChannel> chm
= new ConcurrentHashMap<Integer, SocketChannel>();
private static int msg = 0; public static void main(String args[]) throws Exception {
Selector selector = Selector.open();
// Open a listener on each port, and register each one
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
InetSocketAddress address = new InetSocketAddress("localhost",PORT);
ssc.bind(address);
ssc.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Going to listen on " + PORT);
while (true){
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> it = selectedKeys.iterator(); System.out.println(selectedKeys.size());
while (it.hasNext()){
String msg = new String();
SelectionKey key = (SelectionKey) it.next();
if(key.isAcceptable()){
ServerSocketChannel sscNew = (ServerSocketChannel) key
.channel();
SocketChannel sc = sscNew.accept();
sc.configureBlocking(false);
// Add the new connection to the selector
sc.register(selector, SelectionKey.OP_READ);
// Add the socket channel to the list
chm.put(sc.hashCode(), sc);
it.remove();
}else if(key.isReadable()){
SocketChannel sc = (SocketChannel) key.channel();
int code = 0;
while ((code = sc.read(echoBuffer)) > 0) {
byte b[] = new byte[echoBuffer.position()];
echoBuffer.flip();
echoBuffer.get(b);
msg+=new String(b, "UTF-8");
}
// if(msg.length()>1)
// msg = msg.substring(0, msg.length()-2); //client关闭时,收到可读事件,code = -1
if (code == -1 ||
msg.toUpperCase().indexOf("BYE")>-1){
chm.remove(sc.hashCode());
sc.close();
} else {
//code=0,消息读完或者echoBuffer空间不够时,部分消息内容下一次select后收到
echoBuffer.clear();
}
System.out.println("msg: " + msg + " from: " + sc + "code: " + code );
it.remove(); //注册可写通知
sc.register(selector,SelectionKey.OP_WRITE);
}else if(key.isWritable()){
SocketChannel client = (SocketChannel) key.channel();
String sendTxt = "Message from Server";
sendBuffer.put(sendTxt.getBytes());
sendBuffer.flip();
int code = 0; //如果sendBuffer内容一次没有写完,会在下一次事件中处理吗?
while (client.write(sendBuffer) != 0){
}
if (code == -1 ){
chm.remove(client.hashCode());
client.close();
} else {
//code=0,消息写完
sendBuffer.clear();
}
it.remove();
System.out.println("Send message to client "); //在读通知里面注册为写事件,所以这里还需要注册为读,否则不在接受客户端消息
client.register(selector,SelectionKey.OP_READ);
}
}
Thread.sleep(5000);
}
}
}

使用windows telnet与服务端交互,在windows telnet中,需要使用send命令来按行发送消息,如下所示

一些说明:

1.select操作为阻塞操作,直至至少一个事件发生

2.server端只需注册accept事件

3.read、write为非阻塞操作,需要在代码中判断返回结果

4.read操作,如果接受的buffer大小不够,会在下一次select操作中接受

5.write操作呢?如果消息没有发完,怎么处理,下面这种循环么?

while (buffer.hasRemaining()){
socketChannel.write(buffer);
}

6.register会覆盖,所以在读写处理中交替注册

Java NIO网络编程demo的更多相关文章

  1. Netty | 第1章 Java NIO 网络编程《Netty In Action》

    目录 前言 1. Java 网络编程 1.1 Javs NIO 基本介绍 1.2 缓冲区 Buffer 1.2 通道 Channel 1.3 选择器 Selector 1.4 NIO 非阻塞网络编程原 ...

  2. Java NIO 网络编程基础

    Java NIO提供了一套网络api,可以用来处理连接数很多的情况.他的基本思想就是用一个线程来处理多个channel. 123456789101112131415161718192021222324 ...

  3. java基础-网络编程(Socket)技术选型入门之NIO技术

    java基础-网络编程(Socket)技术选型入门之NIO技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传统的网络编程 1>.编写socket通信的MyServer ...

  4. Java面向对象 网络编程 下

    Java面向对象 网络编程  下 知识概要:                   (1)Tcp 练习 (2)客户端向服务端上传一个图片. (3) 请求登陆 (4)url 需求:上传图片. 客户端:   ...

  5. 二十三、Java基础--------网络编程

    Java中另一个重要技术就是网络编程了,为了更好的学习web方向的知识,有必要对java之网络编程好好学习,本文将围绕网络编程技术进行分析. 常见的网络协议:UDP.TCP UDP 1. 将数据源和目 ...

  6. JAVA的网络编程

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

  7. Java Socket 网络编程心跳设计概念

    Java Socket 网络编程心跳设计概念   1.一般是用来判断对方(设备,进程或其它网元)是否正常动行,一 般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉.用于 ...

  8. 20145325张梓靖 实验五 "JAVA的网络编程"

    20145325张梓靖 实验五 "JAVA的网络编程" 实验内容 使用 JVAV语言 进行网络编程 对明文进行加密 设计过程 我完成的是客户端,服务端同伴 20145308刘昊阳 ...

  9. 【转】JAVA之网络编程

    转自:火之光 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者 ...

随机推荐

  1. 重闯Sqli-labs关卡第三天(6-10关)

    第六关(双注入GET双引号字符型注) 核心代码: 1 $id = '"'.$id.'"'; 2 $sql="SELECT * FROM users WHERE id=$i ...

  2. 面试半年,凭借这份JVM面试题,我终于拿到了字节跳动的offer!

    内存区域 虚拟机栈生命周期与线程相同,描述的是Java 方法执行的内存模型,每个方法在执行的时候都会创建一个栈帧,用于存取局部变量表.操作数栈.动态链接.方法出口等信息本地方法栈与虚拟机栈作用相似,只 ...

  3. TCP的ACK机制

    下面是整个的tcp的三次握手和四次挥手的协议 TCP四次挥手 在客户端先发送一个FIN的包,表示要close(),客户端想和连接断开,发完之后出于FIN_WAIT_1状态下:服务端收到之后就变成CLO ...

  4. Android light系统分析

    光线系统包括:背光,闪光,led指示灯   一.内核层     Led-class.c (kernel-3.10\drivers\leds) 这个文件给HAL层提供接口     led_brightn ...

  5. 全面解析RayFire的动态对象与静态对象

    我们在日常使用RayFire的过程中,接触得比较多的应该就是RayFire的对象设置了.RayFire的对象包含了动态对象.静态对象与休眠对象,其中动态对象.静态对象可以结合动力学.运动学概念设置动作 ...

  6. guitar pro系列教程(五):Guitar Pro音轨属性之小节的功能

    又到了guitar pro系列教程新的一章,本章节小编将采用图文相结合的方式与大家一起来讨论下关于Guitar Pro小节的功能,感兴趣的小伙伴都可以进来看看哦,如下图所示: 我们看到小节这选项栏中分 ...

  7. Ubuntu sudo 出现unable to resolve host 解决方法

    Ubuntu sudo 出现unable to resolve host 解决方法 Ubuntu环境, 假设这台机器名字叫abc(机器的hostname), 每次执行sudo 就出现这个警告讯息: s ...

  8. C语言模拟实现先来先服务(FCFS)和短作业优先(SJF)调度算法

    说明 该并非实现真正的处理机调度,只是通过算法模拟这两种调度算法的过程. 运行过程如下: 输入进程个数 输入各个进程的到达事件 输入各个进程的要求服务事件 选择一种调度算法 程序给出调度结果:各进程的 ...

  9. 使用celery异步发送短信

    目录 1.使用celery异步发送短信 1.1在celery_task/mian.py中添加发送短信函数 1.2在verifcations/views.py中添加celery发送短信视图函数 1.3 ...

  10. try...catch的前世今生

    1975年, John Goodenough发表论文,提出异常处理的建议: 一是明确声明命令可能抛出何种异常: 二是需要有将可能出错的操作括起来的语句结构. Communications of the ...