C++ boost asio何时调用async\u read\u一些回调?

C++ boost asio何时调用async\u read\u一些回调?,c++,asynchronous,boost,boost-asio,C++,Asynchronous,Boost,Boost Asio,为了理解boostasio库,我实现了一个异步echo服务器。我要求tcp::socket对少量数据执行async\u-read\u-some,即9个字节(选择测试为一个小数字),即socket\u.async\u-read\u-some(boost::asio::buffer(buf,9),回调)。然后,我向服务器提供少量数据,而read命令似乎只在有整整9个字节要读取时才回调,而不是像我预期的那样在写入(比如)4个字节后立即回调。什么决定回调何时发生?为什么套接字上的某些数据可用时回调不立即

为了理解boostasio库,我实现了一个异步echo服务器。我要求
tcp::socket
对少量数据执行
async\u-read\u-some
,即9个字节(选择测试为一个小数字),即
socket\u.async\u-read\u-some(boost::asio::buffer(buf,9),回调)
。然后,我向服务器提供少量数据,而read命令似乎只在有整整9个字节要读取时才回调,而不是像我预期的那样在写入(比如)4个字节后立即回调。什么决定回调何时发生?为什么套接字上的某些数据可用时回调不立即发生?

该操作的完成条件与其同步对应的操作相同。如果出现以下情况之一,则认为操作已完成:

  • 已成功接收一个或多个字节的数据
  • 发生错误,将阻止接收数据
操作完成(成功或失败)后,将发布到
io\u服务
,以进行延迟调用。此时,为
io\u服务的任何线程都可以调用ReadHandler


当向套接字写入少量数据时,例如在问题描述中,人们通常会观察到由于以下原因,在后续数据写入套接字之前不发送数据的行为。简言之,许多系统将尝试通过将小型出站消息连接到单个消息中,然后发送来缓解IP/TCP拥塞。要在每个套接字的基础上显式禁用此行为,请设置选项:

boost::asio::ip::tcp::socket套接字(io\u服务);
// ...
boost::asio::ip::tcp::no_延迟选项(true);
插座。设置_选项(选项);

如有疑问,请使用数据包分析器(如Wireshark或tcpdump)在发送方和接收方上监控有线通信量。通常可以使用这些工具快速确定问题是在发送端还是在接收端。在识别出问题的一方后,通常必须深入内核、驱动程序或硬件文档,以识别可能是问题根源的配置。

当操作系统发出数据可用的信号时,确实会发生这种情况。这在很大程度上取决于硬件缓冲区、IRQ级别等。它基本上是由实现定义的。@sehe因此,如果我使用
asyn\u read\u some
,我对boost调用没有什么不同之处?当套接字打开并且有数据要读取时,我可能永远不会被回调?您可以调整sysctls和驱动程序参数。也许您可以使用特定的硬件。您可以在发送端禁用。您可以确保没有路由设备重新安排数据包等。也就是说,我认为即使启用了say Nagle的算法(TCP连接上的默认设置),允许的延迟也有最低保证。所以“当套接字打开并且有数据要读取时,我可能永远不会被回调?”似乎不是真的。但我没有任何消息来源与此相关。(应该不难找到,真的)@sehe我看到的是我正在从一个小测试客户端手动写入tcp套接字。在测试服务器上,当async_read_some返回时,它将
fprintf(stderr,stuff)
。我会写几个字符,服务器就会坐在那里。只有在写了足够多的东西之后,它才做了一些事情,足够的是9。它看起来确实会永远挂在那里,因为有几个字符被发送出去了。