2015-07-09 73 views
2

试着了解boost asio库,我实现了一个异步回显服务器。我要求tcp::socket为少量数据做一个async_read_some,即9个字节(选择测试为一个小数字),即socket_.async_read_some(boost::asio::buffer(buf, 9), callback)。然后,我将少量数据提供给服务器,并且读取命令只有在完整的9个字节才能读取时回调,而不是在写入后立即写入,例如4个字节,正如我所料。什么决定了什么时候回调发生,以及为什么一旦有一些数据在套接字上可用就不会发生?什么时候升压asio调用async_read_some回调?

+0

当操作系统发出数据可用时,确实会发生这种情况。这很大程度上取决于硬件缓冲区,IRQ级别等。它基本上是实现定义的。 – sehe

+0

@sehe因此,如果我使用'asyn_read_some',那么对于boost调用我就没有​​什么不同了?即当套接字打开并且有数据要被读取时,我可能永远不会被回调? –

+0

您可以调整sysctls和驱动程序参数。也许你可以使用特定的硬件。您可以在发送端禁用[Nagle算法](https://en.wikipedia.org/wiki/Nagle's_algorithm)。您可以确保没有路由设备重新排列数据包等。 – sehe

回答

2

socket.async_read_some()操作具有与其同步对应操作socket.read_some()相同的完成条件。

  • 一个或多个数据字节已被成功接收
  • 时发生的错误,将防止从正在接收

一旦操作完成(成功数据:当任一操作被认为是完整的或失败),则ReadHandler将被发布到io_service中用于延期调用。此时,ReadHandler可以由服务于io_service的任何线程调用。


当数据的少量正被写入的插座,如在问题描述,一个典型地观察到没有被发送,直到随后的数据被写入到由于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的,在发送器和接收器两者。通常可以使用这些工具快速确定问题是发送方还是接收方。在识别违规端时,通常需要深入到内核,驱动程序或硬件文档中,以确定可能成为问题根源的配置。

相关问题