有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

网络JavaNIOSocketchannel编写问题

我正在使用JavaNIO的SocketChannel编写:int n = socketChannel.write(byteBuffer);大多数情况下,数据是以一个或两个部分发送的;i、 e.如果一次尝试无法发送数据,则重试剩余数据

这里的问题是,有时,一次尝试没有完全发送数据,其余的数据在多次尝试发送时,即使尝试了几次,也没有一个字符写入通道,最后在一段时间后发送发回的数据。此数据可能不大,可能约为2000个字符

这种行为的原因可能是什么?内存、操作系统等外部因素是否会导致延迟

请帮我解决这个问题。如果需要任何其他信息,请告诉我。 谢谢

编辑:

在NIO SocketChannel中是否有一种方法可以在实际写入之前检查通道是否可以提供要写入的数据。这里的意图是,在尝试写入完整数据之后,如果某些数据尚未写入通道,那么在写入剩余数据之前,我们可以检查SocketChannel是否可以获取更多数据;因此,负责写入此数据的线程可以等待或执行其他操作,而不是多次徒劳的尝试


共 (2) 个答案

  1. # 1 楼答案

    TCP/IP是一种流协议。在任何级别的任何地方,都不能保证您发送的数据不会被拆分为单字节段,或者在您编写数据时,不会被拆分为介于单字节段和单字节段之间的任何内容

    你的期望是错误的

    如果重新编辑,则当套接字发送缓冲区填满时,write()将返回零。当你得到它时,为OP_WRITE注册通道并停止写入循环。当你得到OP_WRITE时,注销它(非常重要)并继续写作。如果write()再次返回零,请重复

  2. # 2 楼答案

    在使用TCP时,我们只能在套接字缓冲区填满之前(而不是之后)在发送方端套接字通道上进行写操作。因此,如果接收方消耗数据的速度较慢,发送方端的套接字缓冲区就会填满,正如您所提到的,write()可能会返回零

    在任何情况下,当发送方有一些数据要发送时,我们都应该使用OP_WRITE将SocketChannel注册到选择器,作为感兴趣的操作,当选择器返回SelectionKey时,请选中key。isWritable()并尝试在该频道上写入。正如上面Nilesh提到的,在写入完整数据后,不要忘记用选择器注销OP_写入位