Aba*_*oub -2 c++ boost race-condition boost-asio
bool Connection::Receive(){
std::vector<uint8_t> buf(1000);
boost::asio::async_read(socket_,boost::asio::buffer(buf,1000),
boost::bind(&Connection::handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
int rcvlen=buf.size();
ByteBuffer b((std::shared_ptr<uint8_t>)buf.data(),rcvlen);
if(rcvlen <= 0){
buf.clear();
return false;
}
OnReceived(b);
buf.clear();
return true;
}
Run Code Online (Sandbox Code Playgroud)
该方法工作正常,但仅当我在其中创建断点时才有效。等待接收的时间是否有问题?没有断点,什么也收不到。
您试图在启动异步操作后立即从接收缓冲区读取数据,而不等待它完成,这就是为什么在设置断点时它可以工作的原因。
async_read之后的代码属于Connection::handler,因为这是您告诉async_read接收一些数据后调用的回调。
您通常需要一个start_read和一个handle_read_some功能:
void connection::start_read()
{
socket_->async_read_some(boost::asio::buffer(read_buffer_),
boost::bind(&connection::handle_read_some, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void connection::handle_read_some(const boost::system::error_code& error, size_t bytes_transferred)
{
if (!error)
{
// Use the data here!
start_read();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意shared_from_this,如果您希望通过未完成的I / O请求数来自动处理连接的生命周期,则这一点很重要。确保从派生您的类,boost::enable_shared_from_this<connection>并仅使用创建它make_shared<connection>。
为了实现这一点,您的构造函数应该是私有的,您可以添加一个朋友声明(C ++ 0x版本;如果编译器不支持此声明,则您必须自己插入正确数量的参数):
template<typename T, typename... Arg> friend boost::shared_ptr<T> boost::make_shared(const Arg&...);
Run Code Online (Sandbox Code Playgroud)
还要确保在调用回调时您的接收缓冲区仍处于活动状态,最好使用连接类的静态大小的缓冲区成员变量。