boost::asio 中对单个套接字的多次写入
如果您尝试在前一个完成之前对 boost::asio 套接字进行第二次写入,我找不到任何关于会发生什么的信息。这似乎在许多异步程序中可能会发生(因为在执行第一次写入后,程序将在等待其完成之前继续,可能导致发送第二条消息,依此类推)。我想到了一些可能发生的事情(假设在所有情况下消息都是通过对 async_write 的一次调用来发送的)。
void handleWrite(const boost::system::error_code&error)
{
if(error)throw NetError(error);
}
vodi sendStuff()
{
const char msg1 = "Red, Green, Blue";
const char msg2 = "One, Two, Three";
asio::async_write(socket,asio::buffer(msg1,sizeof(msg1)),boost::bind(&handleWrite,_1));
//assume msg1 has still not been sent by the time we get here
asio::async_write(socket,asio::buffer(msg2,sizeof(msg2)),boost::bind(&handleWrite,_1));
}
因此,假设第一次发送不会导致错误:
- Asio 按顺序发送 msg1,然后发送 msg2,即使在单个 TCP 数据包中也可能
- 第二个 async_write 调用会阻塞,直到 msg1 完成
- 结果未定义
如果 msg1s 中发生错误,我假设异常也会导致 msg2 中止?
如果关联的 io_service 有线程池,或者只有一个线程,这也会受到影响吗?
如果它不安全,那么是否有人编写了某种简单的包装器来维护要发送的消息队列,将它们一一发送并在任何写入处理程序抛出异常时中止?
I couldn't find any thing about what happens if you try to do a second write to a boost::asio socket before a previous one completed. This seems like something that could potentially happen in many asynchronous programs (since after doing the first write, the program will then continue before waiting for it to finish, potentially causing a second message to be sent and so on). I've thought of a few possible things that could happen (this is assuming that in all cases the message is sent with a single call to async_write).
void handleWrite(const boost::system::error_code&error)
{
if(error)throw NetError(error);
}
vodi sendStuff()
{
const char msg1 = "Red, Green, Blue";
const char msg2 = "One, Two, Three";
asio::async_write(socket,asio::buffer(msg1,sizeof(msg1)),boost::bind(&handleWrite,_1));
//assume msg1 has still not been sent by the time we get here
asio::async_write(socket,asio::buffer(msg2,sizeof(msg2)),boost::bind(&handleWrite,_1));
}
So assuming that the first send doesn't cause an error:
- Asio sends msg1, then msg2, in order, possible even in a single TCP packet
- The second async_write call blocks until msg1 is done
- The result is undefined
If an error occurs in msg1s, i'm assuming the exception will cause msg2 to abort as well?
Also is this effected by if the associated io_service has a thread pool, or just a single thread?
If it's not safe, then has any one written some kind of simple wrapper that maintains a queue of messages to send, sending them one by one and aborting if any write handler throws an exception?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,使用普通的非阻塞套接字,您可以向套接字写入一些与实现相关的内容,然后最终写入将返回 -EWOULDBLOCK 并且不执行写入,以便您可以稍后重试。浏览源代码告诉我,Boost 包装了这一点,因此您编写的所有内容最终都应该到达那里(或引发错误,不包括 will_block 或 try_again)。
So, with normal non-blocking sockets, you can write some implementation-dependant amount of stuff to the socket, then eventually a write will return -EWOULDBLOCK and not do the write so you can retry later. Poking around in the source tells me that Boost wraps that, so that everything you write should get there eventually (or raise an error, not including would_block or try_again).