1. 程式人生 > >Netty進階基礎篇之NIO 非阻塞通訊(6)

Netty進階基礎篇之NIO 非阻塞通訊(6)

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