Java NIO 学习笔记 - SocketChannel

为了进行非阻塞的socket通信,java nio提供Channel概念的实现。Channel概念以区别于传统的基于流概念的IO。事实上Channel概念的IO既包括非阻塞式的IO也包括阻塞式IO。要Channel完成非阻塞式IO需要实现SelectableChannel接口,与Selector关联使用。SocketChannel就是这样一个SelectableChannel。

由于,selector机制本身涉及多线程的内容,与Channel关联使用较为复杂;所以这里只以片断方式,针对SocketChannel的功能进行说明简要说明。

1。创建服务端的ServerSocketChannel

关联的ServerSocket可以侦听一个port。

ServerSocketChannel sschannel; ... sschannel = ServerSocketChannel.open(); //设置为no block方式工作 sschannel.configureBlocking(false); //关联的server-socket开始侦听 address = new InetSocketAddress(port); ServerSocket ss = sschannel.socket(); ss.bind(address);  

2。将ServerSocketChannel注册(帮定)到一个selector用于等待外来socket连接。

当一个server socket channel得到一个外部socket连接时,可以将一个底层连接创建为一个SocketChannel实例。再将这个SocketChannell注册(帮定)到一个selector用于具体IO。

//server socket channel注册到selector sschannel.register(selector, SelectionKey.OP_ACCEPT); ... // 当一个server socket channel得到一个外部socket连接时 // 可以把该底层连接创建出一个 SocketChannel SocketChannel sc = ssc.accept(); sc.configureBlocking(false); //设置为非阻塞方式 // 将SocketChannel 注册到一个selector用于IO sc.register(selector, SelectionKey.OP_READ, request);

3。当SocketChannel可以读取或写出时则可以用SocketChannel 的方法进行IO。

读取:

ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); buffer.clear(); // 具体的读取动作,sc将底层socket缓存数据写输入bytebuffer对象。 int n = sc.read(buffer); //读取数据后的几种情况 if(n < 0){ //读取数据失败,socket连接可能已经断开。 ... }else if(n > 0){ //具体处理buffer对象 ... }else{ //n == 0的情况 }  

写出:

ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); ... // 填充buffer buffer.clear(); buffer.put(data); buffer.filp(); // 具体的写出 sc.write(buffer);  

 

4。另一方面,以Client方式创建SocketChannel。

SocketChannel sc = SocketChannel.open(); sc.configureBlocking(false); sc.connect("127.0.0.1",1000); sc.finishConnect(); 

 

 

你可能感兴趣的:(Java,NIO)