【问题标题】:How to flush a SocketChannel in Java NIO?如何在 Java NIO 中刷新 SocketChannel?
【发布时间】:2011-09-16 05:32:20
【问题描述】:

在 Java IO 中,OutputStream 可以使用flush() 方法来确保一次发送数据。

SocketChannel在Java NIO中有对应的函数吗?据我所知,FileChannel 有一个force() 方法可以刷新数据。

可能是个很幼稚的问题……

【问题讨论】:

    标签: java nio


    【解决方案1】:

    OutputStream.flush() 除了刷新堆栈中任何BufferedOutputStreams 或ObjectOutputStreams 或PrintStreams 的缓冲区外,什么都不做。

    具体来说,它不执行任何与FileChannel.force()getFD().sync() 对应的操作。它只是将来自 JVM 的流缓冲区刷新到(在这种情况下)内核中的套接字发送缓冲区。

    SocketChannel.write() 根本不涉及任何此类缓冲:它直接进入内核中的套接字发送缓冲区。所以没有什么要flush,所以没有flush操作。

    【讨论】:

    • 谢谢!进一步了解 NIO :-)
    • 看起来某处有一个缓冲区(可能是提到的“套接字发送缓冲区”) - 如果您在写入数据后过早关闭流,它不会被发送。但我不知道等到缓冲区为空的方法。看起来对于 HTTP 连接,一旦客户端收到它所期望的所有数据,客户端就会关闭客户端->服务器流,因此如果您让服务器从客户端读取直到流关闭,您可以将其用作一个信号,即数据成功了。
    【解决方案2】:

    当你 force() 将数据写入磁盘时,操作系统可以确定它已成功写入磁盘。然而,TCP 通信更复杂,数据要经过操作系统控制之外的许多阶段。一般来说,操作系统会尽快结束数据,并且不会将套接字数据(通常约为 64 KB)缓冲到缓冲磁盘写入(有时是 GB)的程度

    确保成功接收数据的最佳方法是让另一端发送响应。

    如果您希望尽可能快地发送数据,您可以尝试关闭 nagle,但是大多数操作系统在优化此功能方面非常聪明,并且将其关闭并不会产生太大的影响。

    【讨论】:

    • 我刚刚发现的一件事:socketChannel.setOption(StandardSocketOptions.SO_LINGER, N) 告诉系统如果存在未发送的数据,则在关闭通道之前最多等待 N 秒。
    【解决方案3】:

    无法刷新 SocketChannel。您必须检查数据是否已完全发送。

    【讨论】:

    • 是的。但那是针对 FileChannel 的,对吧?我需要为 SocketChannel 提供相同的功能。
    • 无法刷新 SocketChannel。您必须检查数据是否已完全发送。
    • 谢谢。这也是帮助:)。顺便说一句,你能推荐一些链接或书籍来了解 Java NIO。再次感谢!
    • 请查看您的回复?这您的回复。也是错的。
    猜你喜欢
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    相关资源
    最近更新 更多