我很难理解使用async_read和async_write时应该如何构造一个tcp客户端的正确方法。 examples似乎在连接后执行async_read,然后在处理程序中执行async_write。用Async_read和async_write Boost ASIO TCP很难理解几个概念
在我的客户端和服务器的情况下,当客户端连接时,它需要检查要写入的消息队列并检查是否需要读取任何内容。我遇到困难的一件事是了解这将如何异步工作。
我的设想是在async_connect处理程序中,如果sendQueue中有任何内容并反复调用async_read,线程将调用async_write。还是应该检查在执行async_read之前是否有可读的内容?以下是我正在谈论的一个例子。
void BoostTCPConnection::connectHandler()
{
setRunning(true);
while (isRunning())
{
//If send Queue has messages
if (sendSize > 0)
{
//Calls to async_write
send();
}
boost::shared_ptr<std::vector<char> > sizeBuffer(new std::vector<char>(4));
boost::asio::async_read(socket_, boost::asio::buffer(data, size), boost::bind(&BoostTCPConnection::handleReceive, shared_from_this(), boost::asio::placeholders::error, sizeBuffer));
}
}
void BoostTCPConnection::handleReceive(const boost::system::error_code& error, boost::shared_ptr<std::vector<char> > sizeBuffer)
{
if (error)
{
//Handle Error
return;
}
size_t messageSize(0);
memcpy((void*)(&messageSize),(void*)sizeBuffer.data(),4);
boost::shared_ptr<std::vector<char> > message(new std::vector<char>(messageSize));
//Will this create a race condition with other reads?
//Should a regular read happen here
boost::asio::async_read(socket_, boost::asio::buffer(data, size),
boost::bind(&BoostTCPConnection::handleReceiveMessage, shared_from_this(),
boost::asio::placeholders::error, message));
}
void BoostTCPConnection::handleReceiveMessage(const boost::system::error_code& error, boost::shared_ptr<std::vector<char> > rcvBuffer)
{
if (error)
{
//Handle Error
return;
}
boost::shared_ptr<std::string> message(new std::string(rcvBuffer.begin(),rcvBuffer.end()));
receivedMsgs_.push_back(message);
}
void BoostTCPConnection::handleWrite(const boost::system::error_code& error,size_t bytes_transferred)
{
//Success
if (error.value() == 0)
return;
//else handleError
}
@DavidSchwartz我很难组织代码。一个原因是,读或写可能需要在任何时候完成。在这个同步版本中,我只需要使用一个循环并检查是否需要完成并执行它。我想我很难在异步思考。 –
好吧,阅读很容易。在完成连接时调用'async_read',然后在读取处理程序返回之前再次调用它。写操作有点复杂,但您可以随时调用它两种情况:1)您有要写入的数据。 2)您没有已经挂起的异步写入。 –
@DavidSchwartz谢谢。我差不多有async_read了。但调用async_write有我。如果数据可用并且async_write未处于待处理状态,我应该在连接处理程序中有一个循环吗?我可以使用一个strand来串行写入async_write吗? –