TCP_NODELAY如何影响连续的write()调用?

TCP_NODELAY是一个选项,可以快速发送TCP数据包,无论其大小如何。 当速度很重要时,这是非常有用的选项,但是,我很好奇它会对此做些什么:

Socket socket = [some socket]; socket.setTcpNoDelay(true); OutputStream out = socket.getOutputStream(); out.write(byteArray1); out.write(byteArray2); out.write(byteArray3); out.flush(); 

我试图在SocketOutputStream上找到flush实际上做了SocketOutputStream ,但据我所知,它什么也没做。 我曾希望它会告诉套接字“现在发送所有缓冲的数据”,但不幸的是,不,它没有。

我的问题是:这些3字节数组是在一个数据包中发送的吗? 我知道你对TCP构造网络数据包的方式没有多少控制权,但有没有办法告诉套接字(至少尝试)打包这些字节数组,这样可以避免网络开销? 可以手动打包字节数组并在一次调用中发送它们来write帮助吗?

我的问题是:这些3字节数组是在一个数据包中发送的吗?

由于你已经禁用了Nagle算法,几乎可以肯定没有,但你不能100%肯定。

我知道你对TCP构造网络数据包的方式没有多少控制权,但有没有办法告诉套接字(至少尝试)打包这些字节数组

是。 不要禁用Nagle算法。

所以避免网络开销? 可以手动打包字节数组并在一次调用中发送它们来写帮助吗?

是,或者更简单仍然只是将套接字输出流包装在BufferedOutputStream并在您希望发送数据时调用flush() ,这是根据您现有的代码。 你是正确的, flush()在套接字输出流上什么都不做,但是它会刷新BufferedOutputStream.

可以手动打包字节数组并在一次调用中发送它们来写帮助吗?

是的,只需一次通话就可以发送给他们。 这将最大化您在单个数据包中发送字节的机会。

当然,你永远不会知道,因为涉及的变量太多 – 你和你的同伴之间有不同的操作系统和许多不同的网络设备,但如果你让操作系统能够把所有东西打包在一起,它通常会尝试。

如果你禁用nagle并进行单独的系统调用(记住,操作系统控制套接字,而不是你的appliation或java),你要求操作系统单独发送它们。 操作系统不知道您将再次使用更多数据调用write。