5

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

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

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

4

2 回答 2

6

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

由于您禁用了 Nagle 算法,几乎可以肯定不会,但您不能 100% 确定。

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

是的。不要禁用 Nagle 算法。

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

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

于 2013-08-06T22:56:42.283 回答
1

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

是的,只需一次调用即可将它们全部发送给 write。这将最大限度地提高您的字节在单个数据包中发送的机会。

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

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

于 2013-08-06T23:38:35.267 回答