[英]Java NIO. SocketChannel.read method all time return 0. Why?
我試着了解java NIO是如何工作的。 特別是SocketChannel如何工作。
我寫下面的代碼:
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
public class Test {
public static void main(String[] args) throws IOException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("google.com", 80));
while (!socketChannel.finishConnect()) {
// wait, or do something else...
}
String newData = "Some String...";
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
while (buf.hasRemaining()) {
System.out.println(socketChannel.write(buf));
}
buf.clear().flip();
int bytesRead;
while ((bytesRead = socketChannel.read(buf)) != -1) {
System.out.println(bytesRead);
}
}
}
但是,方法socketChannel.read(buf)始終返回0並無限執行。
哪里弄錯了?
因為NIO SocektChannel
在數據可供讀取之前不會阻止。 即,非阻塞通道可以return 0 on read() operation
。
這就是為什么在使用NIO時你應該使用java.nio.channels.Selector ,如果數據可用,它會在通道上提供讀取通知。
另一方面,阻塞通道將等待數據可用並返回可用數據量。 即,阻塞通道return 0 on read() operation
永遠不會return 0 on read() operation
。
您可以在此處閱讀有關NIO的更多信息:
您已經專門配置
socketChannel.configureBlocking(false);
如果你保留了阻塞的默認值,那么你將永遠不會返回0的長度。
在閱讀標題的時候我就是這樣說的:b / c緩沖區中沒有空間:
與目前的答案不同,真正的罪魁禍首是buf.clear().flip();
這有效地設置緩沖區就像position=limit=0
- 因此沒有數據讀取 - 改為buf.clear()
,你很高興。
在發布問題之前,與NIO玩得開心並使用調試器。
如果你真的想使用非阻塞I / O,那么要么使用選擇器,要么使用Java 7中的nio2(AsynchronousSocketChannel等)。使用選擇器很棘手,更好地找到准備好的工作示例。 使用nio2相對容易。
技術說明是您沒有向Google網絡服務器發送完整的HTTP請求,因此在收到完整的請求之前,它不會向您發送回復。
這就解釋了為什么要讀取0字節,這意味着沒有數據可供讀取。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.