public class ServerNio {

    public static void main(String[] args) throws IOException, InterruptedException {
//打开一个selector
Selector selector = Selector.open();
//打开serverSock通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//非阻塞模式
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(8099)); // bind address on port
//向selector注册一个接受客户端事件,如果有客户端想和8099端口建立连接,selector会生成接受连接就绪事件
SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT, 1); try {
while (true) {
System.out.println("in while(true)");
//select 注册的key whose channels are ready for I/O operations
int count = selector.select();
System.out.println("select count:" + count); //在无限循环中,就绪事件个数大于0时,进入逻辑处理流程
if (count > 0) {
//获取就绪事件key
Set<SelectionKey> selectionKeySet = selector.selectedKeys();
Iterator<SelectionKey> selectionKeyIterator = selectionKeySet.iterator(); //遍历就绪的selectionKey
while ((selectionKeyIterator.hasNext())) {
SelectionKey key = selectionKeyIterator.next();
//先remove掉,防止重复处理
selectionKeyIterator.remove(); //如果key是建立连接请求
if (key.isAcceptable()) {
System.out.println("attachment:" + key.attachment());
ServerSocketChannel channel = (ServerSocketChannel) key.channel();
//如果不处理,那么每次都能select到它,接受请求
SocketChannel socketChannel = channel.accept();
socketChannel.configureBlocking(false);
System.out.println("has accept channel");
// socketChannel.socket().setSoTimeout(2000);
//项selector注册读监控事件,可以考虑注册到另一个selector上去,让当前selector只处理accept
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();
if (!sc.isOpen()) {
System.out.println("in continue");
continue;
} //开辟4个byte空间
ByteBuffer byteBuffer = ByteBuffer.allocate(4);
byteBuffer.clear(); //从sc中读取byte到buffer中
int bytesRead = sc.read(byteBuffer);
//断开连接了,-1就是socket关闭的意思
if (bytesRead == -1) {
sc.close();
System.out.println("client is out");
continue;
}
System.out.println("读取的byte个数:" + bytesRead);
if (bytesRead > 0) {
//切换为读模式
byteBuffer.flip();
//由于传输的是一个int,这里尝试将4个byte转回int
int value = 0;
value = value | ((byteBuffer.get(0) & 0xFF) << 24);
value = value | ((byteBuffer.get(1) & 0xFF) << 16);
value = value | ((byteBuffer.get(2) & 0xFF) << 8);
value = value | ((byteBuffer.get(3) & 0xff)); //读取到的值
System.out.println("transport value:int:" + value);
}
// sc.register(selector, SelectionKey.OP_WRITE); } else if (key.isWritable()) {
//类似response
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(4);
byteBuffer.clear();
byteBuffer.putInt(3);
sc.write(byteBuffer);
// sc.register(selector, SelectionKey.OP_READ);
} } System.out.println("selectionKeySize:" + selectionKeySet.size());
}
Thread.sleep(100);
}
} finally {
Thread.sleep(20000);
selector.close();
} } }

最新文章

  1. 定时器 NSTimer 和 CADisplayLink
  2. POJ 1852 Ants (等价思考)
  3. Putty终端 模拟 远程登录 虚拟机Linux
  4. Java http数据MD5、AES、DES加密
  5. HTML——超文本标记语言
  6. Java中构造方法、实例方法、类方法的区别
  7. vue 组件自定义v-model
  8. 第20月第28天 tensorflow
  9. java直接生成zip压缩文件精简代码(跳过txt文件)
  10. Python requests库如何下载一个图片资源
  11. python正则表达式一[转]
  12. python进程池爬取下载美女图片(xpath)--lowbiprogrammer
  13. jqgrid 使用自带的行编辑
  14. [浅谈CSS核心概念] CSS布局模型:float和position
  15. 001 Ajax中XMLHttpRequest的讲解
  16. 系统安装-007 CentOS7yum源添加、删除及其yum优化(转)
  17. MySQL自成一派的查询提示
  18. 大神真会玩~这组C4D动图,我都看了一整天!
  19. 前端框架MVVM是什么(整理)
  20. HBase中的Client如何路由到正确的RegionServer

热门文章

  1. 8.ExecutorService-执行器服务
  2. 【运维】Vmware虚拟机静态IP的设置
  3. php第七天-文件处理系统
  4. spring-dao.xml通常写法
  5. C++实现将一个文件夹内容拷贝至另一个文件夹
  6. ubuntu桌面版修改屏幕刷新率之后无法进入桌面(一直卡在输入密码的界面)的解决办法
  7. 需要完成PAT作业和微博作业的具体方法
  8. ksoap2-android的简单使用
  9. linux 漏洞列表
  10. MATLAB鼠标事件