【发布时间】:2013-10-17 16:05:15
【问题描述】:
我工作的产品使用 Boost ASIO (TCP) 进行网络通信。在一次测试中,我注意到一些非常奇怪的事情:ASIO 会以 ~60MB/s 的速度发送 13 秒,然后下降到 ~300K/s 持续 9 秒,然后又回到 ~60MB/s 持续 13 秒;这将在整个传输过程中重复。我编写了一个测试应用程序,看看我是否可以重现这一点,令我惊讶的是,我可以。
在我的测试应用程序中,客户端和服务器连接后的代码非常基础。值得注意的是,阻塞和非阻塞套接字产生相同的结果。以下是服务器在阻塞情况下接收数据的方式:
while(true)
{
boost::system::error_code ec;
serverSocket.read_some(boost::asio::buffer(serverBuffer, bufferLength), ec);
}
客户端这样做:
while(true)
boost::asio::write(clientSocket, boost::asio::buffer(clientBuffer, bufferLength)
如果 bufferLength 为 4K,我会发现问题,但如果我将其推高到 32K,则传输速度很快 (>120MB/s) 且一致。
谁能解释一下可能发生的事情?这是在 Windows Server 2008 上运行的 Windows 应用程序。
编辑:我进行了 Wireshark 捕获,有时服务器发送 ACK 的延迟超过 150 毫秒。即客户端发送最后一位数据[PSH,ACK];服务器在 150 毫秒后回复 [ACK]。中间没有其他流量。
第二次编辑:我编写了一个表现出相同行为的 C# 应用程序。客户端使用 NetworkStream.Write 发送 4k 数据包,服务器使用 NetworkStream.Read 读取它们。关于从这里去哪里有什么建议吗?
【问题讨论】:
-
是什么让你觉得这种行为是由 asio 库而不是网络堆栈和/或网络本身引起的?
-
很好的问题,我不知道它肯定是 ASIO。我很确定这不是网络。两台测试机直接相连。虽然它可能是网络堆栈,但我不太确定如何证明它是。 (我的背景不是网络)。
-
boost::asio使用底层操作系统特定的网络堆栈,这证实了您在 C# 应用程序上遇到相同问题的发现。你是否设置了套接字缓冲区大小(ioctl SO_SNDBUF/SO_RCVBUF)? -
是的,客户端和服务器上用于发送/接收的套接字缓冲区大小均为 64K。
-
曾经在 asio 上遇到过同样的问题,就我而言,它甚至发生在 localhost 连接上。使用
socket->set_option( boost::asio::socket_base::send_buffer_size( 64*1024 ), ec);增加套接字发送和接收缓冲区有帮助,不再有神秘的延迟,但仍然不知道为什么会发生这种情况,因此无法帮助您。
标签: networking boost-asio