boost::asio::async_write_some - 顺序函数调用
boost::asio::async_write_some - sequential function call
我正在使用 boost.asio 编写应用程序。我有一个 boost::asio::ip::tcp::socket
类型的对象,并且(当然)我有 boost::asio::io_context
,其中 run
的函数仅从一个线程调用。将数据写入套接字有几种方法,但目前我使用套接字的函数async_write_some
,类似于下面的代码:
void tcp_connection::write(packet_ptr packet)
{
m_socket.async_write_some(boost::asio::buffer(packet->data(), packet->size()),
std::bind(&tcp_connection::on_write, this, std::placeholders::_1, std::placeholders::_2, packet));
}
boost::asio
命名空间中还有另一个函数 - async_write
。 async_write
的文档说:
This operation is implemented in terms of zero or more calls to the stream's async_write_some function, and is known as a composed operation. The program must ensure that the stream performs no other write operations (such as async_write, the stream's async_write_some function, or any other composed operations that perform writes) until this operation completes.
在async_write_some
的文档中没有这种'caution'。
这让我有点困惑,我有以下问题:
- 在不等待上一个调用完成的情况下调用
async_write_some
是否安全?据我从 boost 的文档中了解到,我不应该用 async_write
这样做,但是 async_write_some
呢?
- 如果是,数据写入socket的顺序和调用函数的顺序一样吗?我的意思是如果我调用
async_write_some(packet1)
和 async_write_some(packet2)
- 数据包是否会以相同的顺序写入套接字?
- 我应该使用哪个功能?它们有什么区别?
- 在上一个还没有完成的情况下调用
async_write
不安全的原因是什么?
否;其原因可能已记录在底层套接字中 API (BSD/WinSock).
不适用。请注意,调用处理程序的顺序 是 保证匹配它们发布的顺序,因此您可以使用完成的 async_write_some
调用的异步链来解决它处理程序发布下一个写入。这被称为隐式链(参见 https://www.boost.org/doc/libs/master/doc/html/boost_asio/overview/core/async.html and Why do I need strand per connection when using boost::asio?)。
99% 的时间,使用免费功能。不同之处在于它实现了组合操作来发送一个“单元”的信息,即整个缓冲区、消息,或者直到满足给定的完成条件。
async_write_some
是最低级别的构建块,它甚至不能保证写入所有数据:remarks:
The write operation may not transmit all of the data to the peer.
Consider using the async_write
function if you need to ensure that all
data is written before the asynchronous operation completes.
从最严格的意义上讲,这并不是不安全的¹。它只是不会导致正确的结果:这是因为调用处理程序的顺序导致数据以混合顺序写入套接字。
¹(除非您在不同步的情况下并发访问共享 IO 对象)
我正在使用 boost.asio 编写应用程序。我有一个 boost::asio::ip::tcp::socket
类型的对象,并且(当然)我有 boost::asio::io_context
,其中 run
的函数仅从一个线程调用。将数据写入套接字有几种方法,但目前我使用套接字的函数async_write_some
,类似于下面的代码:
void tcp_connection::write(packet_ptr packet)
{
m_socket.async_write_some(boost::asio::buffer(packet->data(), packet->size()),
std::bind(&tcp_connection::on_write, this, std::placeholders::_1, std::placeholders::_2, packet));
}
boost::asio
命名空间中还有另一个函数 - async_write
。 async_write
的文档说:
This operation is implemented in terms of zero or more calls to the stream's async_write_some function, and is known as a composed operation. The program must ensure that the stream performs no other write operations (such as async_write, the stream's async_write_some function, or any other composed operations that perform writes) until this operation completes.
在async_write_some
的文档中没有这种'caution'。
这让我有点困惑,我有以下问题:
- 在不等待上一个调用完成的情况下调用
async_write_some
是否安全?据我从 boost 的文档中了解到,我不应该用async_write
这样做,但是async_write_some
呢? - 如果是,数据写入socket的顺序和调用函数的顺序一样吗?我的意思是如果我调用
async_write_some(packet1)
和async_write_some(packet2)
- 数据包是否会以相同的顺序写入套接字? - 我应该使用哪个功能?它们有什么区别?
- 在上一个还没有完成的情况下调用
async_write
不安全的原因是什么?
否;其原因可能已记录在底层套接字中 API (BSD/WinSock).
不适用。请注意,调用处理程序的顺序 是 保证匹配它们发布的顺序,因此您可以使用完成的
async_write_some
调用的异步链来解决它处理程序发布下一个写入。这被称为隐式链(参见 https://www.boost.org/doc/libs/master/doc/html/boost_asio/overview/core/async.html and Why do I need strand per connection when using boost::asio?)。99% 的时间,使用免费功能。不同之处在于它实现了组合操作来发送一个“单元”的信息,即整个缓冲区、消息,或者直到满足给定的完成条件。
async_write_some
是最低级别的构建块,它甚至不能保证写入所有数据:remarks:The write operation may not transmit all of the data to the peer. Consider using the
async_write
function if you need to ensure that all data is written before the asynchronous operation completes.从最严格的意义上讲,这并不是不安全的¹。它只是不会导致正确的结果:这是因为调用处理程序的顺序导致数据以混合顺序写入套接字。
¹(除非您在不同步的情况下并发访问共享 IO 对象)