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

时间:2013-08-06 22:19:34

标签: java sockets networking tcp

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实际上做了什么,但据我所知,它什么也没做。我曾希望它会告诉套接字“现在发送你所有的缓冲数据”,但不幸的是,不,它没有。

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

2 个答案:

答案 0 :(得分:6)

  

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

由于您已禁用Nagle算法,几乎可以肯定,但您无法100%确定。

  

我知道你无法控制TCP如何构建网络数据包,但有没有办法告诉套接字(至少尝试)打包这些字节数组

是。 不要禁用Nagle算法。

  

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

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

答案 1 :(得分:1)

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

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

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

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