无法关闭TCP_NODELAY

时间:2013-03-08 13:13:47

标签: boost-asio delay nagle

我正在使用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));

代表

boost::asio::ip::tcp::no_delay noDelayOption(false);
m_tcpSocket.set_option(noDelayOption);

我仍然看到PSH标志设置。

我也尝试删除set_option代码并仍然看到它设置。

在Wireshark中,我看到:

104 - 105  SYN
105 - 104  SYN, ACK
104 - 105  ACK
104 - 105  PSH, ACK + my message
105 - 104  ACK

其中104和105是我的2台PC的IP地址。 我对使用我的数据的消息有ACK感到惊讶。

如何关闭NO_DELAY?

2 个答案:

答案 0 :(得分:5)

您的代码看起来好像正确设置TCP_NODELAY开启或关闭。要关闭TCP_NODELAY,请使用:

socket.set_option(boost::asio::ip::tcp::no_delay(false));

TCP RFC将PSH定义为推送功能。简而言之,它是一个标志,通知接收器已发送所有数据,因此将数据转发到协议栈。 Boost.Asio maps它的API到BSD套接字,而BSD套接字不提供控制PSH标志的方法。这通常由协议栈内的内核处理,当它清除缓冲区时。

来自TCP/IP Illustrated

  

此标志通常用于指示发送数据包的一侧的缓冲区已与发送数据包一起清空。换句话说,当设置了PSH位字段的数据包离开发送方时,发送方没有更多数据要发送。

     

[...]

     

推送(接收方应尽快将此数据传递给应用程序 - 不能可靠地实施或使用)。

答案 1 :(得分:2)

NO_DELAY不会更改发送给对等方的标志。它改变了内核的缓冲算法。谷歌关于Nagle算法以获得更多的了解。