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在SocketOutputStream
上的实际作用,但据我所知,它什么都没做。我曾希望它能告诉套接字"立即发送所有缓冲数据",但不幸的是,没有。
我的问题是:这些3字节数组是在一个数据包中发送的吗?我知道你无法控制TCP如何构建网络数据包,但有没有任何方法可以告诉套接字(至少尝试)打包这些字节数组,从而避免网络开销?是否可以手动打包字节数组并在一次调用中发送给write
帮助?
我的问题是:这些3字节数组是在一个数据包中发送的吗?
由于您禁用了Nagle算法,几乎可以肯定不会,但您不能100%确定。
我知道你对TCP如何构建网络数据包没有太多的控制权,但有什么方法可以告诉套接字(至少尝试)打包这些字节数组吗
是的不要禁用Nagle算法。
这样就避免了网络开销?是否可以手动打包字节数组并在一次调用中发送它们以编写帮助?
是的,或者更简单的是,只需将套接字输出流封装在BufferedOutputStream
中,并根据当前代码在希望发送数据时调用flush()
。flush()
对套接字输出流不执行任何操作,但它会刷新BufferedOutputStream.
是否可以手动打包字节数组并在一次调用中发送它们以编写帮助
是的,只需一个电话就可以把它们全部发送出去。这将最大限度地提高您的字节在单个数据包中发送的机会。
当然,你永远不会知道,因为涉及的变量太多了——不同的操作系统和你和你的同龄人之间的许多不同的网络设备,但如果你让操作系统能够将所有东西打包在一起,它通常会尝试
如果你禁用nagle并进行单独的系统调用(记住,操作系统控制套接字,而不是你的应用程序或java),你就要求操作系统单独发送它们。操作系统不知道你会用更多的数据再次调用write。