无法关闭TCP_NODELAY

Ant*_*Ant 1 delay boost-asio 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));
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?

Tan*_*ury 5

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

socket.set_option(boost::asio::ip::tcp::no_delay(false));
Run Code Online (Sandbox Code Playgroud)

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

来自TCP/IP Illustrated:

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

[...]

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