boost asio何时调用async_read_some回调?

时间:2015-07-09 22:34:14

标签: c++ asynchronous boost boost-asio

尝试了解boost asio库,我实现了异步echo服务器。我要求tcp::socket针对少量数据执行async_read_some,即9个字节(选择用于测试为小数字),即socket_.async_read_some(boost::asio::buffer(buf, 9), callback)。然后我向服务器提供少量数据,并且读取命令似乎仅在它有一个完整的9字节要读取时回调,而不是在写入之后立即回拨,比如4字节,就像我预期的那样。是什么决定了回调发生的时间以及为什么一旦套接字上有一些数据可用就不会发生回调?

1 个答案:

答案 0 :(得分:2)

socket.async_read_some()操作与其同步对应socket.read_some()操作具有相同的完成条件。在以下情况之一时,该操作被认为是完成的:

  • 已成功接收一个或多个字节的数据
  • 发生阻止接收数据的错误

完成操作(成功或失败)后,ReadHandler将被发布到io_service以进行延迟调用。此时,服务于io_service的任何线程都可以调用 ReadHandler

当将少量数据写入套接字时(例如在问题描述中),通常会观察到由于Nagle's algorithm将后续数据写入套接字之前未发送数据的行为。简而言之,许多系统将尝试通过将小的出站消息连接成随后发送的单个消息来缓解IP / TCP拥塞。要在每个套接字的基础上显式禁用此行为,请设置boost::asio::ip::tcp::no_delay选项:

boost::asio::ip::tcp::socket socket(io_service);
// ...
boost::asio::ip::tcp::no_delay option(true);
socket.set_option(option);

如有疑问,请使用发送器和接收器上的数据包分析器(如Wireshark或tcpdump)监控线路流量。人们通常可以使用这些工具来快速识别问题是在发送方还是接收方。在确定违规方面后,通常需要深入了解内核,驱动程序或硬件文档,以确定可能是问题根源的配置。