天天看點

【超詳細解釋】從Java NIO到Netty的每一步 (一)

這裡寫目錄标題

  • ​​前言​​
  • ​​Java NIO元件介紹​​
  • ​​Channel​​
  • ​​ServerSocketChannel​​
  • ​​SocketChannel​​
  • ​​關注我日常更新分享Java程式設計技術!希望大家都能早日走上人生巅峰!​​
【超詳細解釋】從Java NIO到Netty的每一步 (一)

前言

由于我之前接觸的架構(Vert.x)或者中間件(Dubbo、RocketMQ)底層均基于Netty實作,再加上Netty越來越受到青睐,是以想學習一下Netty。

又因為看源碼發現很多概念和實作都是基于Java NIO的,是以還是需要先學習一下Java NIO基礎知識。是以學習的思路變為Java NIO -> Netty基本概念 ->Netty源碼。

如果有什麼不對或者不清楚的地方,歡迎大家一起讨論。

Java NIO元件介紹

Channel

Channel 有點象流。 資料可以從Channel讀到Buffer中,也可以從Buffer寫到Channel中。這裡有個圖示:

【超詳細解釋】從Java NIO到Netty的每一步 (一)

下面是JAVA NIO中的一些主要Channel的實作:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

    接下來我們主要講SocketChannel和ServerSocketChannel

ServerSocketChannel

ServerSocketChannel 是一個可以監聽新進來的TCP連接配接的通道,就像标準IO中的ServerSocket一樣。

代碼樣例:

//打開ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//監聽端口9999
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
//設定為非阻塞模式
serverSocketChannel.configureBlocking(false);
while(true){
    //設定為非阻塞模式會導緻accept方法立即傳回,是以可能傳回null
    SocketChannel socketChannel =
            serverSocketChannel.accept();
    //do something with socketChannel...
}      

SocketChannel

SocketChannel是一個連接配接到TCP網絡套接字的通道。如1.1中,當一個連接配接到達時可以建立一個SocketChannel。

  1. 将SocketChannel的資料讀到buffer中:
ByteBuffer buf = ByteBuffer.allocate(2048);
int bytesRead = socketChannel.read(buf);      

read()方法傳回的int值表示讀了多少位元組進Buffer裡。如果傳回的是-1,表示已經讀到了流的末尾(連接配接已經關閉)。

  1. 将buffer的資料寫入SocketChannel
String newData = "hello world";
//Buffer操作後面章節介紹
ByteBuffer buf = ByteBuffer.allocate(2048);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
while(buf.hasRemaining()) {
    channel.write(buf);
}      

注意write()方法是放到while循環體裡面的,因為沒法保證一次write()會把多少位元組寫到SocketChannel裡。

  1. 非阻塞模式
socketChannel.configureBlocking(false);      

write():在非阻塞模式下,write()方法在尚未寫出任何内容時可能就傳回了。

read():在非阻塞模式下,read()方法在尚未讀取到任何資料時可能就傳回了。

非阻塞模式适合與Selector搭配使用,通過将一或多個SocketChannel注冊到Selector,可以詢問Selector哪個Channal已經準備好了讀取,寫入等,是以接下來介紹一下Selector。

關注我日常更新分享Java程式設計技術!希望大家都能早日走上人生巅峰!