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

use*_*011 2 java sockets nio socketchannel

我试着了解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);

        }

    }

}
Run Code Online (Sandbox Code Playgroud)
  1. 我尝试连接到谷歌服务器.
  2. 发送请求到服务器;
  3. 从服务器读取答案.

但是,方法socketChannel.read(buf)始终返回0并无限执行.

哪里弄错了?

Ram*_*PVK 6

因为NIO SocektChannel在数据可供读取之前不会阻塞.即,非阻塞通道可以return 0 on read() operation.

这就是为什么在使用NIO时你应该使用java.nio.channels.Selector,如果数据可用,它会在通道上提供读取通知.

另一方面,阻塞通道将等待数据可用并返回可用数据量.即,阻止频道永远不会return 0 on read() operation.

您可以在此处阅读有关NIO的更多信息:


Pet*_*rey 5

您已专门配置

socketChannel.configureBlocking(false);
Run Code Online (Sandbox Code Playgroud)

如果保留默认值阻止,则永远不会返回0的长度。