io-nio-socket步步为营(三)NIO
2017-10-17 18:11
357 查看
原理:
运用reactor模式
Selector是核心-分发器A multiplexor of SelectableChannel objects。
能检测任意个注册过的channel上的事件,并分发事件,内部实现不用考虑,封装的好处。
client没必要用NIO,使用http://luckywnj.iteye.com/blog/1744283中的client
server,
需要多线程的么?workthread?如何写?
运用reactor模式
Selector是核心-分发器A multiplexor of SelectableChannel objects。
能检测任意个注册过的channel上的事件,并分发事件,内部实现不用考虑,封装的好处。
client没必要用NIO,使用http://luckywnj.iteye.com/blog/1744283中的client
server,
需要多线程的么?workthread?如何写?
/** * @author timeriver.wang * @version 2013-1-7 11:50:33 PM */ public class NIOServer { public static void main(String[] args) throws Exception { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().bind(new InetSocketAddress(8899)); serverSocketChannel.configureBlocking(false); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); Charset charset = Charset.forName("UTF-8"); CharsetDecoder decoder = charset.newDecoder(); CharsetEncoder encoder = charset.newEncoder(); ByteBuffer clientBuffer = ByteBuffer.allocate(1024); while (true) { // 貌似两个client同时连,返回也是1?在select处阻塞,这样避免线程卡死耗尽资源? // int sel = selector.select(); int sel = selector.select(3000); if (sel == 0) { continue; } Set<SelectionKey> set = selector.selectedKeys(); System.out.println(set.size()); Iterator<SelectionKey> keyIter = set.iterator(); while (keyIter.hasNext()) { SelectionKey key = keyIter.next(); System.out.println(key); // channel is ready to accept a new socket connection if (key.isAcceptable()) { SocketChannel serverChannel = ((ServerSocketChannel) key.channel()).accept(); // 为serverChannel再设置一次否则,java.nio.channels.IllegalBlockingModeException, serverChannel.configureBlocking(false); SelectionKey skey = serverChannel.register(key.selector(),SelectionKey.OP_READ); System.out.println("acceptable: serverChannel="+serverChannel+",skey="+skey); }else if (key.isReadable()) {// channel is ready for reading SocketChannel serverChannel = (SocketChannel) key.channel(); clientBuffer.clear(); long bytesRead = serverChannel.read(clientBuffer); if (bytesRead == -1) { serverChannel.close(); } else { clientBuffer.flip(); String receivedMsg = decoder.decode(clientBuffer).toString(); System.out.println("receive msg: " + receivedMsg); SelectionKey skey = serverChannel.register(selector,SelectionKey.OP_WRITE); System.out.println("readable "+skey); skey.attach(receivedMsg); } } else if (key.isWritable()) { //channel is ready for writing SocketChannel serverChannel = (SocketChannel) key.channel(); String sendMsg = (String) key.attachment(); ByteBuffer block = encoder.encode(CharBuffer.wrap("Hello !"+sendMsg)); serverChannel.write(block); SelectionKey skey = serverChannel.register(key.selector(),SelectionKey.OP_READ); System.out.println("write "+skey); } keyIter.remove(); } } } }
相关文章推荐
- io-nio-socket步步为营(一)流基础
- io-nio-socket步步为营(二)传统IO
- io-nio-socket步步为营(四)异步AIO
- io-nio-socket步步为营(五)netty框架
- io-nio-socket步步为营(六)SSL
- io-nio-socket步步为营(七) IO模型-心得体会
- io-nio-socket步步为营(八)实践练习
- IO与NIO对于异步Socket的处理
- Java IO 和 NIO 分别实现简单的Socket
- 第七篇:Java NIO Socket VS 标准IO Socket
- 【Java TCP/IP Socket】Java NIO Socket VS 标准IO Socket
- IO(一):传统IO(基于字符,字节,Socket) 与BIO,NIO,AIO 介绍
- java socket IO和NIO的对比
- JAVA SOCKET IO VS NIO
- IO(一):传统IO(基于字符,字节,Socket) 与BIO,NIO,AIO 介绍
- 【Java TCP/IP Socket】Java NIO Socket VS 标准IO Socket
- Java Socket IO(BIO、NIO)
- Java NIO Socket VS 标准IO Socket
- 传统Socket IO与NIO的比较
- Socket通信之BIO(同步阻塞IO)、PAIO(伪异步阻塞IO)、NIO(异步非阻塞IO)、AIO(异步非阻塞IO)、netty5之IO