Netty進階基礎篇之NIO 非阻塞通訊(6)
阿新 • • 發佈:2019-07-14
1、Tcp網路非阻塞通訊
//客戶端 @Test public void client() throws IOException{ //1. 獲取通道 SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8085)); //2. 切換非阻塞模式 sChannel.configureBlocking(false); //3. 分配指定大小的緩衝區 ByteBuffer buf = ByteBuffer.allocate(1024); //4. 傳送資料給服務端 String str = "mujiutian"; while(!StringUtils.isEmpty(str)){ buf.put((new Date().toString() + "\n" + str).getBytes()); buf.flip(); sChannel.write(buf); buf.clear(); str = ""; } //5. 關閉通道 sChannel.close(); } //服務端 @Test public void server() throws IOException{ //1. 獲取通道 ServerSocketChannel ssChannel = ServerSocketChannel.open(); //2. 切換非阻塞模式 ssChannel.configureBlocking(false); //3. 繫結連線 ssChannel.bind(new InetSocketAddress(8085)); //4. 獲取選擇器 Selector selector = Selector.open(); //5. 將通道註冊到選擇器上, 並且指定“監聽接收事件” ssChannel.register(selector, SelectionKey.OP_ACCEPT); //6. 輪詢式的獲取選擇器上已經“準備就緒”的事件 while(selector.select() > 0){ //7. 獲取當前選擇器中所有註冊的“選擇鍵(已就緒的監聽事件)” Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while(it.hasNext()){ //8. 獲取準備“就緒”的是事件 SelectionKey sk = it.next(); //9. 判斷具體是什麼事件準備就緒 if(sk.isAcceptable()){ //10. 若“接收就緒”,獲取客戶端連線 SocketChannel sChannel = ssChannel.accept(); //11. 切換非阻塞模式 sChannel.configureBlocking(false); //12. 將該通道註冊到選擇器上 sChannel.register(selector, SelectionKey.OP_READ); }else if(sk.isReadable()){ //13. 獲取當前選擇器上“讀就緒”狀態的通道 SocketChannel sChannel = (SocketChannel) sk.channel(); //14. 讀取資料 ByteBuffer buf = ByteBuffer.allocate(1024); int len = 0; while((len = sChannel.read(buf)) > 0 ){ buf.flip(); System.out.println(new String(buf.array(), 0, len)); buf.clear(); } } //15. 取消選擇鍵 SelectionKey it.remove(); } } }
2、Udp網路非阻塞通訊
@Test public void send() throws IOException{ DatagramChannel dc = DatagramChannel.open(); dc.configureBlocking(false); ByteBuffer buf = ByteBuffer.allocate(1024); Scanner scan = new Scanner(System.in); while(scan.hasNext()){ String str = scan.next(); buf.put((new Date().toString() + ":\n" + str).getBytes()); buf.flip(); dc.send(buf, new InetSocketAddress("127.0.0.1", 9898)); buf.clear(); } dc.close(); } @Test public void receive() throws IOException{ DatagramChannel dc = DatagramChannel.open(); dc.configureBlocking(false); dc.bind(new InetSocketAddress(9898)); Selector selector = Selector.open(); dc.register(selector, SelectionKey.OP_READ); while(selector.select() > 0){ Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while(it.hasNext()){ SelectionKey sk = it.next(); if(sk.isReadable()){ ByteBuffer buf = ByteBuffer.allocate(1024); dc.receive(buf); buf.flip(); System.out.println(new String(buf.array(), 0, buf.limit())); buf.clear(); } } it