在写了关于TCP_NODELAY和TCP_CORK 的答案之后,我意识到我对TCP_CORK的细节点的了解一定是缺乏的,因为我不清楚为什么Linux开发人员认为有必要引入新的TCP_CORK标志,而不仅仅是依赖于应用程序在适当的时间设置或清除现有的TCP_NODELAY标志.
特别是,如果我有一个Linux应用程序想要通过TCP流发送()一些小的/非连续的数据片段而不支付200mS Nagle延迟税,同时最小化发送所需的数据包数量它,我可以这两种方式中的任何一种:
使用TCP_CORK(伪代码):
int optval = 1;
setsockopt(sk, SOL_TCP, TCP_CORK, &optval, sizeof(int)); // put a cork in it
send(sk, ..);
send(sk, ..);
send(sk, ..);
optval = 0;
setsockopt(sk, SOL_TCP, TCP_CORK, &optval, sizeof(int)); // release the cork
Run Code Online (Sandbox Code Playgroud)
或者使用TCP_NODELAY(伪代码):
int optval = 0;
setsockopt(sk, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int)); // turn on Nagle's
send(sk, ..);
send(sk, ..);
send(sk, ..);
optval = 1;
setsockopt(sk, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(int)); // turn Nagle's back off
Run Code Online (Sandbox Code Playgroud)
多年来我一直在使用后一种技术并取得了良好的效果,并且它具有可移植到非Linux操作系统的优点(尽管在Linux之后你必须在关闭Nagle之后再次调用send(),以便确保数据包立即发送并避免Nagle-delay - send()'零字节就足够了).
现在Linux开发人员都很聪明,所以我怀疑上面的TCP_NODELAY用法从未发生过.必须有一些理由让他们认为这是不够的,这导致他们引入了一个新的/专有的TCP_CORK标志.任何人都能解释一下这个原因是什么吗?
有办法通过命令行吗?man tcp告诉我,我需要设置tcp_nodelay = 1,但我无法在/ proc/sys/net/ipv4下创建tcp_nodelay文件.如果有任何方法可以在Linux中禁用Nagle,请告诉我.
我一直认为Nagle的算法会影响两个方向的套接字,并且该设置TCP_NODELAY以某种方式通知远程端也关闭Nagle.
这是正确的,还是设置TCP_NODELAY只会影响调用它的结束行为?
最近,我在服务器端的延迟ACK和客户端的Nagle算法的组合,产生了可识别的40ms延迟,这里记录了:http://www.boundary.com/blog/2012/ 05 /知-A-延迟纳格尔算法,和你/
解决这个问题的最简单方法是在客户端使用TCP_NODELAY(或TCP_CORK也可以在我们的情况下使用).但是,我没有直接控制客户端,并想尝试服务器端修复.似乎TCP_QUICKACK选项在这里可以解决问题,因为服务器会立即发出ACK,导致客户端的Nagle算法无延迟地发送下一个数据包.
令人惊讶的是,我找不到任何人在尝试之前的任何参考.这是一个坏主意(除了我们将发送更多,可能是无偿的ACK)这一事实?由于看起来这个选项看起来不像任何nginx配置,所以最好直接修补nginx(也许是http://hg.nginx.org/nginx/file/dcae651b2a0c/src/http/ngx_http_request. c#l3025)?
谢谢!
I am sending commands to a stepper motor system using Ethernet. The commands get the motor to move, or respond with drive status, or configure the drive, etc... The stepper motor system sometimes hangs, or fails to execute the command, and the manufacturer having looked over everything I supplied has told me to turn off the PSH flag in the TCP layer.
A screenshot of Wireshark showing the use of the PSH flag by my code:
I am using C++11 …
我在Azure上看到了很多关于在WCF中禁用Nagle算法的帖子.我一直想知道这是否仅适用于Azure,或者这应该是更通用的最佳实践.
如各种来源所述,Nagle算法基本上将小TCP请求批处理为单个更大的请求.批量发生在每个连接的基础上.
我在专业环境中看到的大多数WCF传输都是小块数据,由单个线程发送,大多数是双向的.我知道这对于Nagle算法来说并不是理想的情况.
那么......我的结论是否正确,在使用WCF或SOAP时,无论上下文如何,最好始终禁用它?
根据这篇Socket FAQ文章,Nagle的算法是众多算法中的一种,它可以使一堆数据驻留在TCP缓冲区而不会触及线路.Nagle算法的延迟可达200ms.
出于某种原因,Nagle的算法可以完全关闭,但不能只刷一次.这对我来说真是令人费解.为什么没有办法说"只是这一次,不要等待更多的数据.就好像Nagle的200ms一样."
这不是完美的意义,并且在没有Nagle,Nagle和从头开始实现自己的协议之间取得良好的平衡吗?
是否有人知道如何在使用socket.io时配置nagle的算法(开或关)?
这个选项是否随socket.io一起提供?
我假设默认行为配置为使用nagle算法(如果我错了请纠正我).
理想情况下,我希望在不同的应用程序中根据需要使用socket.io来配置nagle的算法(开/关) - 无论我使用哪个Web/app服务器.
谢谢!
我想使用.NET 4.5 ClientWebSocket(http://msdn.microsoft.com/en-us/library/system.net.websockets.clientwebsocket%28v=vs.110%29.aspx),但Wireshark透露,Nagle的算法被打开,这是一个痛苦的脖子.谁能告诉我如何到达ClientWebSocket的Socket.NoDelay属性?即使是黑客也会受到赞赏......
如果我要创建一个TCP_NODELAY启用了该选项的TCP套接字并将其listen用于新连接,是否accept也将TCP_NODELAY启用由返回的新套接字?
不同的套接字可以具有不同的配置选项,尽管有意义的是,由所返回的套接字accept从产生它们的侦听套接字继承其选项。是否依赖于实现?
我需要在python2.6中禁用nagle算法。我发现以这种方式在 httplib.py 中修补 HTTPConnection
def connect(self):
"""Connect to the host and port specified in __init__."""
self.sock = socket.create_connection((self.host,self.port),
self.timeout)
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True) # added line
Run Code Online (Sandbox Code Playgroud)
就可以了。
显然,如果可能的话,我想避免修补系统库。所以,问题是:做这样的事情的正确方法是什么?(我对 python 很陌生,很容易在这里错过一些明显的解决方案)
在许多UNIX TCP实现中,提供了一个套接字选项TCP_CORK,允许调用者绕过Nagle算法并明确指定何时发送物理数据包.Windows(Winsock)中是否有相同的功能?
TCP_CORK(自Linux 2.2起)
如果设置,请不要发送部分帧.再次清除该选项时,将发送所有排队的部分帧.这对于在调用sendfile(2)之前预先添加标头或用于吞吐量优化非常有用.正如目前实施的那样,TCP_CORK的输出时间上限为200毫秒.如果达到此上限,则自动发送排队的数据.自Linux 2.5.71起,此选项只能与TCP_NODELAY结合使用.此选项不应用于可移植的代码中.
(我知道TCP_NODELAY,但这不是我需要的;我仍然希望在发送缓冲区中累积多次写入,然后在我准备好发送物理数据包时触发TCP堆栈.)
我正在使用Boost asio发送TCP消息.我设置了NO_DELAY选项,因为这是一个"实时"控制系统.我看到使用Wireshark在消息中设置了PSH标志.我对性能表示满意,并且按预期工作.
为了兴趣,我决定关闭NO_DELAY并测量性能差异.
我交换了现有的代码:
m_tcpSocket.open(boost::asio::ip::tcp::v4());
boost::asio::ip::tcp::no_delay noDelayOption(true);
m_tcpSocket.set_option(noDelayOption);
// snip create endpoint
m_tcpSocket.connect(m_tcpServerEndpoint);
// snip build message
m_tcpSocket.send(boost::asio::buffer(pDataBuffer, size));
Run Code Online (Sandbox Code Playgroud)
对于
boost::asio::ip::tcp::no_delay noDelayOption(false);
m_tcpSocket.set_option(noDelayOption);
Run Code Online (Sandbox Code Playgroud)
我仍然看到PSH标志设置.
我也尝试删除set_option代码并仍然看到它设置.
在Wireshark中我看到:
104 - 105 SYN
105 - 104 SYN, ACK
104 - 105 ACK
104 - 105 PSH, ACK + my message
105 - 104 ACK
Run Code Online (Sandbox Code Playgroud)
其中104和105是我的2台PC的IP地址.我对使用我的数据的消息有ACK感到惊讶.
如何关闭NO_DELAY?