试着了解boost asio库,我实现了一个异步回显服务器。我要求tcp::socket
为少量数据做一个async_read_some
,即9个字节(选择测试为一个小数字),即socket_.async_read_some(boost::asio::buffer(buf, 9), callback)
。然后,我将少量数据提供给服务器,并且读取命令只有在完整的9个字节才能读取时回调,而不是在写入后立即写入,例如4个字节,正如我所料。什么决定了什么时候回调发生,以及为什么一旦有一些数据在套接字上可用就不会发生?什么时候升压asio调用async_read_some回调?
2
A
回答
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的,在发送器和接收器两者。通常可以使用这些工具快速确定问题是发送方还是接收方。在识别违规端时,通常需要深入到内核,驱动程序或硬件文档中,以确定可能成为问题根源的配置。
相关问题
- 1. 升压ASIO async_read_some超时
- 2. 升压ASIO超时
- 3. 回调传递给boost :: asio :: async_read_some在boost :: asio :: read_some返回数据时从未调用
- 4. 什么时候调用setDataTimeout?
- 5. 什么时候调用webview.clearData
- 6. 什么时候调用robot.cleanUp()
- 7. 什么时候调用onSizeChanged()?
- 8. 什么时候Cocoa回调给定controll?
- 9. 什么时候在rails中调用after_touch回调
- 10. 什么时候使用hash()调用__eq__?
- 11. 什么时候应该调用SharedPreferencesBackupHelper()/ BackupAgent?
- 12. 什么时候应该调用setContentAspectRatio?
- 13. 什么时候可以调用BarcodeScanner.GetDefaultAsync()?
- 14. 什么时候TGraphicControl.Paint被调用?
- 15. 什么时候在Linq中调用OnValidate?
- 16. 什么时候应该调用Transaction.delistResource()?
- 17. 什么时候initWithCoder被调用?
- 18. BackgroundTransferService - TransferProgressChanged什么时候被调用?
- 19. 什么时候ExecutionContext#reportFailure(Throwable)被调用?
- 20. 什么时候ConvertBack方法被调用?
- 21. 什么时候在winforms中调用LayoutEngine?
- 22. 什么时候执行performSelectorOnMainThread调用?
- 23. 什么时候调用SQLiteOpenHelper方法?
- 24. 什么时候调用layoutSubviews方法?
- 25. 什么时候应该调用javax.jdo.Query.close(Object)?
- 26. 什么时候InitializeCulture被调用
- 27. 什么时候应该调用Naming.unbind()?
- 28. 什么时候会调用ctor?
- 29. 什么时候onNewPicture()被调用?
- 30. 什么时候应该调用MessageQueue.EndReceive()?
当操作系统发出数据可用时,确实会发生这种情况。这很大程度上取决于硬件缓冲区,IRQ级别等。它基本上是实现定义的。 – sehe
@sehe因此,如果我使用'asyn_read_some',那么对于boost调用我就没有什么不同了?即当套接字打开并且有数据要被读取时,我可能永远不会被回调? –
您可以调整sysctls和驱动程序参数。也许你可以使用特定的硬件。您可以在发送端禁用[Nagle算法](https://en.wikipedia.org/wiki/Nagle's_algorithm)。您可以确保没有路由设备重新排列数据包等。 – sehe