当TCP TX缓冲区填满时,boost::asio会发生什么?

4
我正在努力掌握boost asio,但我很难理解异步接口背后的一些行为。
我有一个简单的客户端和服务器设置。 - 客户端定期调用async_write发送固定数量的数据。 - 服务器定期轮询数据。 - 当服务器停止轮询数据时会发生什么?
我猜服务器操作系统中的各个缓冲区会填满,并且会停止发送ACK包? 无论发生什么,似乎客户端都可以愉快地继续发送数千兆字节的数据,而不接收任何错误回调(当然也不接收任何成功回调)。 我假设客户端操作系统在某个点上停止接受数据包,因为它们不能被发送? 这是否意味着boost :: asio内部缓冲数据? 如果是,请问我能使用socket.cancel()来放弃数据包,以防我不想等待传输?(我需要确保ASIO忘记我的数据包,以便我可以将旧缓冲区重用于新数据包)。
1个回答

3

asio 不会内部缓冲。如果无法向对方传输更多数据,则始终会发出信号。

例如,如果您在 asio 中使用同步写入,则它们将阻塞,直到可以发送数据(或者至少被复制到内核发送缓冲区中)。如果您使用异步写入,则只有在可以发送时才会调用回调/确认。如果您使用非阻塞写入,则会收到 EAGAIN/WOULD_BLOCK 错误。如果您同时使用多个异步写入 - 嗯 - 您不应该这样做,根据 asio 文档,其行为未定义:

此操作是基于对流的 async_write_some 函数进行零次或多次调用实现的,并且称为组合操作。程序必须确保,在此操作完成之前,流不执行任何其他写操作(例如 async_write、流的 async_write_some 函数或执行写作的任何其他组合操作)。

在您的应用程序中保证始终仅执行单个异步写入操作,并在完成写入下一个数据后再次写入。如果需要在其中写入数据,则需要在应用程序内部进行缓冲。


感谢您详细的回答和“一次只能调用一个”的提示。供参考,此答案https://dev59.com/13I-5IYBdhLWcg3wJEwK#1998127也提供了一些见解。 - user2510141

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接