我正在使用 boost::asio 编写一个相当简单的服务器。
对于独立读取和写入套接字的情况,您如何设置 boost::asio async_write() 和 async_read_some() 方法?
大多数 boost 示例都有一个 async_accept() 调用,该调用绑定到一个处理程序,该处理程序最终调用 async_write() 或 async_read() 但不能同时调用两者。
我正在使用 boost::asio 编写一个相当简单的服务器。
对于独立读取和写入套接字的情况,您如何设置 boost::asio async_write() 和 async_read_some() 方法?
大多数 boost 示例都有一个 async_accept() 调用,该调用绑定到一个处理程序,该处理程序最终调用 async_write() 或 async_read() 但不能同时调用两者。
我只在建立连接后直接启动 async_read_some() 。在回调期间,我处理接收到的数据,然后再次启动 async_read_some()。
对于写入部分:一旦有第一个要写入的数据包,我就会调用 async_write。在写入一个数据包时,无法写入其他数据,因此我还使用队列来写入数据。
一些伪代码:
Connection::sendBytes(bytes)
{
if (!sendInProgress) {
socket->async_write_some(bytes, onMessageWritten);
sendInProgress = true;
}
else writeQueue.push_back(bytes);
}
Connection::onBytesWritten()
{
if (writeQueue.size() == 0) {
sendInProgress = false;
}
else {
// Here you can theoretically send all left data at once (using vectored IO) or only some of the data.
// Depending on data size performance will be different.
socket->async_write_some(writeQueue, onBytesWritten);
writeQueue.clear();
}
}
此外,您将需要一些错误处理,并且取决于谁可以调用写方法也锁定。如果您只在驱动 io_service 的单个线程中进行写入调用,那么这会容易得多,因为所有读取和写入都发生在同一个线程(事件循环)中并且您不会锁定。例如,如果您在 onBytesReceived 处理程序中调用 sendBytes,就会出现这种情况。