不同的SelectableChannel所支持的操作是不同的。例如ServerSocketChannel代表一个ServerSocket,它就只支持OP_ACCEPT操作;

当Selector上注册的所有Channel都没有需要处理的IO操作的时候,select方法将会被阻塞,调用该方法的线程被阻塞。

int select();//默认阻塞
int select(long timeout);//设置超时
int selectNow();//立即返回

服务器上的所有的Channel(ServerSocketChannel 和 SocketChannel)都需要向selector注册。

服务器端需要使用ServerSocketChannel来监听客户端的连接请求。

ServerSocketChannel server = ServerSocketChannel.open();
InetSocketAddress isa = new InetSocketAddress("127.0.0.1",30000);
server.bind(isa);
server.configureBlocking(false);
server.register(selector,SelectionKey.OP_ACCEPT);

监听到客户端连接请求时,返回一个SocketChannel实例。


服务器端:

package com.nanhao.server;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;public class Server {private Selector selector = null;static final int PORT = 30000;static final int BUFFSIZE = 1024;//定义实现编码解码的字符集对象private Charset charSet = Charset.forName("UTF-8");public void init()throws IOException{selector = Selector.open();ServerSocketChannel server = ServerSocketChannel.open();InetSocketAddress isa = new InetSocketAddress("127.0.0.1",PORT);server.bind(isa);//设置ServerSocket以非阻塞的方式进行server.configureBlocking(false);//将server注册到selector里面(每个套接字具有的注册功能)server.register(selector, SelectionKey.OP_ACCEPT);while(selector.select()>0){for(SelectionKey sk:selector.selectedKeys()){//一旦正在处理这个套接字,那么就要先从集合中删除这个套接字selector.selectedKeys().remove(sk);if(sk.isAcceptable()){SocketChannel sc = server.accept();//设置非阻塞模式sc.configureBlocking(false);//将该套接字注册到selector里面sc.register(selector,SelectionKey.OP_READ);//将之前的sk修改为准备接受其他请求sk.interestOps(SelectionKey.OP_ACCEPT);}if(sk.isReadable()){SocketChannel sc = (SocketChannel)sk.channel();//定义准备接受数据的BUFFERByteBuffer buff = ByteBuffer.allocate(BUFFSIZE);String context = "";//开始读取数据try{while(sc.read(buff)>0){buff.flip();//实现解码context += charSet.decode(buff);}System.out.println("读取的数据:"+context);//将此套接字对应的channel设置成准备下一次读取sk.interestOps(SelectionKey.OP_READ);//如果捕获到该SK对应的channel出现异常的话,即表明该channel对应的client出现了问题//所以从Selector里面取消sk的注册。}catch(IOException io){sk.cancel();if(sk.channel() !=null){sk.channel().close();}}if(context.length()>0){for(SelectionKey key :selector.keys()){//获取key对应的channelChannel targetChannel = key.channel();if(targetChannel instanceof SocketChannel){SocketChannel dest = (SocketChannel) targetChannel;//实现编码dest.write(charSet.encode(context));}}}}}}}public static void main(String[]args) throws IOException{new Server().init();}}

客户端:

package com.nanhao.client;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Scanner;public class Client{private Selector selector =null;static final int PORT=30000;static final int BUFFSIZE = 1024;private Charset charset = Charset.forName("UTF-8");//创建客户端套接字private SocketChannel sc = null;public void init()throws IOException {selector = Selector.open();InetSocketAddress isa = new InetSocketAddress("127.0.0.1",PORT);//调用静态open方法创建连接到指定主机的SocketChannelsc = SocketChannel.open();//设置非阻塞的模式sc.configureBlocking(false);//注册到Selectorsc.register(selector, SelectionKey.OP_READ);//启动读取服务器端数据库数据的线程new ClientThread().start();//创建键盘输入流Scanner scanner = new Scanner(System.in);while(scanner.hasNextLine()){String line = scanner.nextLine();//将键盘的内容写到SocketChannelsc.write(charset.encode(line));}}private class ClientThread extends Thread {public void run(){try{while(selector.select()>0){//遍历每个IO可用的channel对应的SelectorKeyfor(SelectionKey sk :selector.selectedKeys()){selector.selectedKeys().remove(sk);if(sk.isReadable()){SocketChannel sc = (SocketChannel)sk.channel();//创建buffByteBuffer byteBuffer = ByteBuffer.allocate(BUFFSIZE);String context = "";while(sc.read(byteBuffer)>0){//清空内存byteBuffer.flip();context += charset.decode(byteBuffer);}System.out.println("聊天信息:"+context);sk.interestOps(SelectionKey.OP_READ);}}}}catch(IOException io){io.printStackTrace();}}}public static void main(String[]args) throws IOException{new Client().init();}
}

NIO : selector、channel、buffer的实例相关推荐

  1. NIO核心之Channel,Buffer和Selector简介

    在NIO的API中,Channel就是实现非阻塞的组件,而事件分发(Dispatcher)使用的是Selector组件,在传统的I/O流(Stream)是有方向的,而NIO支持双向读写,这样就需要将流 ...

  2. java之NIO(Channel,Buffer,Selector)

    java之NIO 1 什么是NIO Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API.NIO支持面向缓冲区的.基于通道的IO操作 ...

  3. Java NIO 编程:Buffer、Channel、Selector原理详解

    1 Java 中的 I/O模型:BIO.NIO.AIO 1.1 BIO.NIO.AIO概念介绍 I/O 模型简单的理解:就是 用什么样的通道进行数据的发送和接收,很大程度上决定了程序通信的性能. Ja ...

  4. Netty导学之NIO,Channel、Buffer、Selector详解

    介绍 NIO可翻译为Non-Blocking IO非阻塞IO,也可以称其为New IO 因为其是JDK1.4新出现的. java中的流要么是输入流,要么是输出流,不可能都是,它面向流编程.而在NIO中 ...

  5. 反射 Nio channel Buffer

    1.反射     1.反射的简介         java的反射机制 在运行状态中 对于任意一个类 都能知道任意一个类的所有属性和方法         对于任意一个对象 都能够调用它的任意一个属性和方 ...

  6. Java NIO Selector详解(含多人聊天室实例)

    一.Java NIO 的核心组件 Java NIO的核心组件包括:Channel(通道),Buffer(缓冲区),Selector(选择器),其中Channel和Buffer比较好理解 简单来说 NI ...

  7. NIO:与 Buffer 一起使用 Channel

    如前文所述,Channel实例代表了一个与设备的连接,通过它可以进行输入输出操作.实际上Channel的基本思想与我们见过的普通套接字非常相似.对于TCP协议,可以使用ServerSocketChan ...

  8. Java NIO之Channel(通道)

    **Java高级特性增强-NIO 本部分网络上有大量的资源可以参考,在这里做了部分整理并做了部分勘误,感谢前辈的付出,每节文章末尾有引用列表~ 写在所有文字的前面:作者在此特别推荐Google排名第一 ...

  9. NIO 之 Channel

    可参考之前写过的文章:NIO 之 Channel实现原理 概述 通道( Channel)是 java.nio 的主要创新点.它们既不是一个扩展也不是一项增强,而是全新.极好的 Java I/O 示例, ...

  10. buffer java nio_Java NIO深入理解Buffer(缓冲区)

    前言 Github:https://github.com/yihonglei/java-all Project:java-nio 一 Buffer概述 Java NIO中的Buffer用于和NIO通道 ...

最新文章

  1. 机器学习,就用Python!五大专家详解其优势何在
  2. 数据库选型绕不开“CAP定理”是什么
  3. 伺服驱动器接线怎么画_百格拉伺服驱动器维修常见故障现象及处理方法
  4. UVa10382 - Watering Grass(贪心算法)
  5. linux存储--虚拟内存详解MMU、页表(十)
  6. python3 import导入模块
  7. 湘潭大学计算机科学收调剂吗,山西师范大学、华侨大学、湘潭大学接受研究生调剂!...
  8. GPU云服务器深度学习性能模型初探
  9. linux查看文件夹下每个文件大小,linux查看当前文件夹下每个文件大小
  10. js与C#服务端 json数据交互
  11. log日志java web_Javaweb项目中使用Log4j记录日志
  12. 【Themes for IntelliJ-based IDEs】Idea主题下载
  13. iOS之深入解析Hash在iOS中的应用
  14. PointCNN程序简介
  15. K3 Cloud 数据库查询表常用语句
  16. Kaggle比赛——预测未来销售(三)
  17. 备了安的网站换服务器,tipask网站更换服务器后 问答系统重新安装注意要点 - 小俊学习网...
  18. win7已经阻止此发行者在您的计算机上运行软件,Win7系统提示Windows已经阻止此软件因为无法验证发行者解决方法...
  19. windows下 搭建 wxWidgets 开发环境
  20. 怎么理解预训练模型?

热门文章

  1. QT 中使用 c++ 的指针
  2. android app自动化测试之UIAutomator
  3. ipsec在企业网中的应用(IKE野蛮模式)
  4. web前端开发工具整理
  5. H265的国标PS流打包
  6. Windows下Caffe的学习与应用(一)——训练自己的数据模型(GoogleNet)
  7. Intent传递对象
  8. java正则hitend,Java Matcher hitEnd()用法及代码示例
  9. 格式说明_法律文书:公司单位民事起诉状格式范本及说明,最高人民法院2016...
  10. Python导出Excel图表