Java NIO框架Netty教程(七)
阿新 • • 發佈:2018-12-23
經過簡單的瞭解,筆者大膽的猜測和”武斷”一下該問題的原因。
首先,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次。)原因應該就是如此。跟我們開始猜的差不多,只是不敢確認。