java - 当socketChannel.read(BUFFER)将返回0时

标签 java sockets socketchannel

我有一个从 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();
        }
    }

下面是客户端写入 SocketChannel 的客户端:

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);
        }
    }

所以我的问题:

  • 恰好在服务器代码中,count 值为 0 (while ((count = socketChannel.read(BUFFER)) > 0))?
  • 如果服务器已读取客户端发送的消息的一半,即 count 是否有可能为 0,即 假设客户端写了:stackoverflow,那么服务端读取stack后,有没有可能count为0,即客户端发送的消息的一半(认为消息大小可以是1MB)?

最佳答案

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

当使用非阻塞模式时,大多数时候你会得到 0,事实上,只要没有数据包在等待你。

在 TCP 中,数据以数据包的形式发送,而不是以消息的形式发送。这意味着如果您发送 1 MB,很可能它会被分成您的 MTU 大小的数据包,例如〜1500 字节。如果您读取此套接字,您很可能会看到此大小的 block 或多个 block (如果自上次读取以来有多个数据包进入)。您永远不会看到数据包的一部分,除非您读取的数据少于可用数据。例如如果 1500 字节正在等待,而您只读取了 8 字节,那么您将获得该数据包的一部分。

关于java - 当socketChannel.read(BUFFER)将返回0时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20868269/

相关文章:

java - ActionScript 3 中的按位运算与 Java 的比较

python - C TCP Echo Server - 数据仅在 close() 时显示

android - 使用 Android Studio 和 Socket 创建用户登录页面

python - 验证域的脚本

java - Selector.select() 开始无限循环

java - 当客户端已打开时处理 ServerSocketChannel 重新启动的连接

java - 更改@ConfigurationProperties 中的分隔符以读取列表属性

Java UDP 通信小程序到 UDP 服务器

java - 如何在前台打开 chrome 驱动程序(使用 Selenium Webdriver)。默认情况下它在没有焦点的背景中打开

java - 关闭套接字 channel 后进一步清理