我正在使用Boost.Asio来编写我正在编写的服务器应用程序.
async_send要求调用者保持正在发送的数据的所有权,直到数据成功发送.这意味着我的代码(看起来像下面这样)会失败,而且它会失败,因为data它将不再是一个有效的对象.
void func()
{
std::vector<unsigned char> data;
// ...
// fill data with stuff
// ...
socket.async_send(boost::asio::buffer(data), handler);
}
Run Code Online (Sandbox Code Playgroud)
所以我的解决方案是做这样的事情:
std::vector<unsigned char> data;
void func()
{
// ...
// fill data with stuff
// ...
socket.async_send(boost::asio::buffer(data), handler)
}
Run Code Online (Sandbox Code Playgroud)
但现在我想知道我是否有多个客户端,我是否需要为每个连接创建一个单独的向量?
或者我可以使用那个单一的载体吗?如果我能够使用那个单一的向量,如果我覆盖其中的内容会弄乱我发送给我所有客户端的数据吗?
Eug*_*nca 13
一个可能的解决方法是使用a shared_ptr来保存你的本地vector并更改处理程序的签名以接收一个,shared_ptr以便延长data发送完成之前的生命(感谢Tim指出这一点):
void handler( boost::shared_ptr<std::vector<char> > data )
{
}
void func()
{
boost::shared_ptr<std::vector<char> > data(new std::vector<char>);
// ...
// fill data with stuff
// ...
socket.async_send(boost::asio::buffer(*data), boost:bind(handler,data));
}
Run Code Online (Sandbox Code Playgroud)
我通过将一个shared_ptr数据传递给处理函数来解决了类似的问题.由于asio在调用之前保留了处理程序仿函数,并且hander仿函数保留了shared_ptr引用,因此只要有一个打开的请求,数据就会保持分配状态.
编辑 - 这是一些代码:
这里连接对象保持正在写入的当前数据缓冲区,因此shared_ptr是连接对象,并且bind调用将方法仿函数附加到对象引用,并且asio调用使对象保持活动状态.
关键是每个处理程序必须使用另一个引用启动新的asyc操作,否则连接将被关闭.一旦完成连接或发生错误,我们就会停止生成新的读/写请求.需要注意的是,您需要确保在所有回调中检查错误对象.
boost::asio::async_write(
mSocket,
buffers,
mHandlerStrand.wrap(
boost::bind(
&TCPConnection::InternalHandleAsyncWrite,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
void TCPConnection::InternalHandleAsyncWrite(
const boost::system::error_code& e,
std::size_t bytes_transferred)
{
Run Code Online (Sandbox Code Playgroud)
但现在我想知道我是否有多个客户端,我是否需要为每个连接创建一个单独的向量?
是的,尽管每个向量不需要在全局范围内.此问题的典型解决方案是保留buffer作为对象的成员,并将该对象的成员函数绑定到传递给async_write完成处理程序的仿函数.这样,缓冲区将在异步写入的整个生命周期内保留在范围内.asio 示例充斥着使用this和使用绑定成员函数的这种用法shared_from_this.一般来说,优选的是使用shared_from_this以简化对象的寿命,尤其是在面部的io_service:stop()和~io_service().虽然对于简单的例子,这种脚手架通常是不必要的.
上述销毁序列允许程序通过使用shared_ptr <>来简化其资源管理.如果对象的生命周期与连接的生命周期(或其他一些异步操作序列)相关联,则对象的shared_ptr将绑定到与其关联的所有异步操作的处理程序中.
一个好的起点是异步回显服务器,因为它简单.
boost::asio::async_write(
socket,
boost::asio::buffer(data, bytes_transferred),
boost::bind(
&session::handle_write,
this,
boost::asio::placeholders::error
)
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10029 次 |
| 最近记录: |