1. 程式人生 > >Java NIO框架Netty教程(七)

Java NIO框架Netty教程(七)

經過簡單的瞭解,筆者大膽的猜測和”武斷”一下該問題的原因。

首先,Selector機制讓我們註冊一個感興趣的事件,然後只要有該事件發生,就會傳遞給接收端。我們寫了三次,接收端一定會出發三次的。

然後,Netty實現機制裡,有個Buffer緩衝池,把收到的資訊都快取在裡面,通過一個執行緒統一處理。也就是我們看到的那個buffer的處理過程。Netty的設定中,有一個一次性最多讀取位元組大小的設定。並且,事件的觸發是在處理過緩衝池中的訊息之後。我們再來回顧一下Netty中讀取資訊的那段程式碼:

ByteBuffer bb = recvBufferPool.acquire(predictedRecvBufSize
); try { while ((ret = ch.read(bb)) > 0) { readBytes += ret; if (!bb.hasRemaining()) { break; } } failure = false; } catch (ClosedChannelException e) { // Can happen, and does not need a user attention.
} catch (Throwable t) { fireExceptionCaught(channel, t); } if (readBytes > 0) { bb.flip(); final ChannelBufferFactory bufferFactory = channel.getConfig().getBufferFactory(); final ChannelBuffer buffer = bufferFactory
.getBuffer(readBytes); buffer.setBytes(0, bb); buffer.writerIndex(readBytes); recvBufferPool.release(bb); // Update the predictor. predictor.previousReceiveBufferSize(readBytes); // Fire the event. fireMessageReceived(channel, buffer); } else { recvBufferPool.release(bb); }

可以看到,如果沒有讀取到位元組是不會觸發事件的,所以我們可能會收到2次或者3次資訊。(如果發的快,解析的慢,後兩次資訊,一次性讀取了,就2次,如果傳送間隔長,分次解析,就收到3次。)原因應該就是如此。跟我們開始猜的差不多,只是不敢確認。