我在我的应用程序中使用 boost asio。我创建了两个 ioservices。一种用于处理 UDP 套接字异步操作,另一种用于处理 tcp 异步操作。在通过 udp 套接字接收数据时,根据数据,我将打开与其他服务器的 tcp 连接。我在所有地方都使用异步函数调用。
下面是高级伪代码。
int g_requestID ;
// boost async_recv handler
class UDPSocket
{
UDPSocket::OnDataReceived(const boost::system::error_code& error, std::size_t bytes_transferred
{
TCPSession *pSesson = new TCPSession() ;
g_requestID = pSesson->sendDataOverTCP(data);
}
}
// TCP Response Callback
void tcpResponse(int reqId)
{
if (g_requestID == reqId)
{
// received response for the request
}
}
class TCPSession
{
boost::asio::streambuf request_;
static int requestId ;
boost::tcp::socket m_socket ;
int currentsessionId = requestId ++ ;
int sendDataOverTCP(char* address, char* data)
{
m_socket.async_resolve()
return currentsessionId++ ;
}
void handle_resolve(const boost::system::error_code& err, tcp::resolver::iterator endpoint_iterator)
{
if (!err)
{
boost::asio::async_connect(m_socket, endpoint_iterator, boost::bind(&client::handle_connect, this, boost::asio::placeholders::error));
}
else
{
std::cout << "Error: " << err.message() << "\n";
}
}
void handle_connect(const boost::system::error_code& err)
{
if (!err)
{
// The connection was successful. Send the request.
boost::asio::async_write(m_socket, request_, boost::bind(&client::handle_write, this, boost::asio::placeholders::error));
}
else
{
std::cout << "Error: " << err.message() << "\n";
}
}
void handle_write(const boost::system::error_code& err)
{
if (!err)
{
boost::asio::async_read_until(socket_, response_, "\r\n", boost::bind(&client::handle_receive, this, boost::asio::placeholders::error));
}
else
{
std::cout << "Error: " << err.message() << "\n";
}
}
void handle_receive(const boost::system::error_code& err)
{
if (!err)
{
tcpResponse(currentsessionId) ;
}
else
{
std::cout << "Error: " << err << "\n";
}
}
}
现在来解决我的问题。在 tcpResponse 函数中,g_requestID 包含垃圾值。当我通过添加日志语句进行调试时,我发现在接收到 tcpResponse 回调后返回了 sendDataOverTCP。在 sendDataOverTcp 内,我只调用 async_resolve。它应该立即返回。但事实并非如此。
调试后,我发现以下行为。async_resolve 正在按预期工作。它立即返回。但 sendDataOverTCP 仅在 tcpResponse 回调后返回。
任何人都可以为我提供解决方案,是因为一些线程调度吗?
相同的代码在 Windows 上运行良好。在linux上,我正面临这个问题。
我使用虚拟框在 ubuntu 13.04 上使用 boost 1.53.0