簡體   English   中英

Java NIO。 SocketChannel.read方法一直返回0.為什么?

[英]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);

        }

    }

}
  1. 我嘗試連接到谷歌服務器。
  2. 發送請求到服務器;
  3. 從服務器讀取答案。

但是,方法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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM