async_readとasync_writeを使用するときにtcpクライアントを構造化する正しい方法を理解するのに苦労しています。例では、接続後にasync_readを実行し、ハンドラーにasync_writeがあるようです。
私のクライアントとサーバーの場合、クライアントが接続するときに、書き込むメッセージのキューをチェックし、何かを読み取る必要があるかどうかをチェックする必要があります。私が苦労していることの1つは、これが非同期でどのように機能するかを理解することです。
私が想像しているのはasync_connectハンドラーで、sendQueueに何かがある場合、スレッドはasync_writeを呼び出し、async_readを何度も呼び出します。または、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
}