Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当socketChannel.read(缓冲区)返回0时_Java_Sockets_Socketchannel - Fatal编程技术网

Java 当socketChannel.read(缓冲区)返回0时

Java 当socketChannel.read(缓冲区)返回0时,java,sockets,socketchannel,Java,Sockets,Socketchannel,我有一个从SocketChannel读取数据的服务器,如下所示: private void readDataFromSocket(SocketChannel socketChannel) throws IOException { BUFFER.clear(); int count = 0; while ((count = socketChannel.read(BUFFER)) > 0) { BU

我有一个从
SocketChannel
读取数据的服务器,如下所示:

private void readDataFromSocket(SocketChannel socketChannel) throws IOException {            
        BUFFER.clear();
        int count = 0;
        while ((count = socketChannel.read(BUFFER)) > 0) {
            BUFFER.flip();
            int limit = BUFFER.limit();
            while (limit > 0) {
                System.out.print((char) BUFFER.get());
                limit--;
            }                
        }            
        if (count < 0) {
            System.out.println("closing the socket!!!");
            socketChannel.close();
        }
    }
因此,我的问题是:

  • 当正好在服务器代码中时,
    count
    值将为0(
    而((count=socketChannel.read(BUFFER))>0)
  • 如果服务器读取了客户端发送的一半消息,即。 假设客户端写入:
    stack overflow
    ,在读取
    stack
    后,服务器中的
    计数是否可能为0,即客户端发送的消息的一半(认为消息大小可能为1MB)

使用阻塞模式时,您将始终获得至少1个字节。注意:您可能只获得1个字节,它不读取“消息”

当使用非阻塞模式时,大多数情况下您将得到0,事实上,只要没有数据包等待着您


在TCP中,数据以数据包而不是消息的形式发送。这意味着如果您发送1 MB,它很可能会被分解为MTU大小的数据包,例如约1500字节。如果您读取此套接字,则很可能会看到此大小的块,或者自上次读取以来,如果有多个数据包传入,则会看到多个数据包。除非您读取的数据少于可用数据,否则您永远不会看到数据包的一部分。e、 g.如果1500字节正在等待,而您只读取了8个字节,则您将获得该数据包的一部分。

那么我如何知道服务器已读取从客户端发送的完整消息?@尝试最常见的方法是先发送长度,例如4字节的int值。当你读了那么多,你就有了一个完整的信息。注意:您可以在一次读取中读取多条消息,并可能读取下一条消息的一部分。您必须处理多条消息和部分读取。看一看ByteBuffer.compact(),它可能很有用。我不能使用请求-响应范例吗。假设客户机发送的内容超过了等待响应的时间(假设只是一个字符,如
),那么它将再次发送其他内容。客户端将在每条消息之后发送
\r\n
。它不会解决所有问题,因为我知道服务器中的消息的结尾是什么,客户端将等待,直到它找到来自服务器的响应。我说的对吗?@尝试正确,您可以使用文本终止符。但是,如果您打算这样做,那么使用BufferedReader可能会简单得多。
private void write(String str, SocketChannel channel) throws IOException{
        byte[] b = str.getBytes();
        buffer.clear();
        buffer.put(b);
        buffer.flip();
        while(buffer.hasRemaining()){
            channel.write(buffer);
        }
    }