[英]boost asio issue within the loop
Could someone help me with folowing questions? 有人可以帮我解决下面的问题吗?
I'm trying to call async_send within the while loop. 我试图在while循环中调用async_send。 The data is sent to server correctly but onSend handler is not called at all... If I do not use the while loop all works fine (the data is sent and received, all handlers ae called) 数据被正确地发送到服务器,但是根本没有调用onSend处理程序...如果我不使用while循环一切正常(数据被发送和接收,所有处理程序都被调用)
Will my code work correctly if we send some msgs before server's answer on previous msgs? 如果我们在服务器的回答之前发送一些msgs,我的代码是否会正常工作?
Here is the TCP client code 这是TCP客户端代码
class TCPClient
{
public:
static const size_t maxBufLen = 100;
static const size_t MAX_INPUT_SIZE = 10;
TCPClient(boost::asio::io_service& IO_Service, tcp::resolver::iterator EndPointIter);
void close();
private:
boost::asio::io_service& m_IOService;
tcp::socket m_Socket;
char recieveBuffer[maxBufLen];
void promptTxMsgLoop();
void onConnect(const boost::system::error_code& ErrorCode, tcp::resolver::iterator EndPointIter);
void onReceive(const boost::system::error_code& ErrorCode);
void onSend(const boost::system::error_code& ErrorCode);
void doClose();
};
TCPClient::TCPClient(boost::asio::io_service& IO_Service, tcp::resolver::iterator EndPointIter)
: m_IOService(IO_Service), m_Socket(IO_Service)
{
tcp::endpoint EndPoint = *EndPointIter;
recieveBuffer[0] = '\0';
m_Socket.async_connect(EndPoint,
boost::bind(&TCPClient::onConnect, this, boost::asio::placeholders::error, ++EndPointIter));
}
void TCPClient::onConnect(const boost::system::error_code& ErrorCode, tcp::resolver::iterator EndPointIter)
{
if (ErrorCode == 0)
{
this->promptTxMsgLoop();
}
else if (EndPointIter != tcp::resolver::iterator())
{
cout << "m_Socket.close();!" << endl;
m_Socket.close();
tcp::endpoint EndPoint = *EndPointIter;
m_Socket.async_connect(EndPoint,
boost::bind(&TCPClient::onConnect, this, boost::asio::placeholders::error, ++EndPointIter));
}
}
void TCPClient::promptTxMsgLoop()
{
recieveBuffer[0] = '\0';
while (true)
{
cout << "> " ;
string tmp;
cin >> tmp;
cout << "Entered: " << tmp << endl;
tmp += "\0";
if (tmp.length() < MAX_INPUT_SIZE-1)
{
try
{
//lock untill buffer is emty
while (strlen(recieveBuffer) > 1)
{
}
//onSend handler is never is called inside while loop
m_Socket.async_send(boost::asio::buffer(tmp.c_str(),tmp.length()+1),
boost::bind(&TCPClient::onSend, this, boost::asio::placeholders::error));
}
catch(exception &e)
{
cerr << "Cannot add msg to send queue... " << e.what() << endl;
}
}
else
cout << "Error: input string is too long. Max length is " << MAX_INPUT_SIZE-1 << endl;
}
}
void TCPClient::onSend(const boost::system::error_code& ErrorCode)
{
cout << "Msg has been sent..." << endl;
if (strlen(recieveBuffer) > 1)
cout << "ERROR: recieveBuffer in not epmty. Data is overritten!" << endl;
if (!ErrorCode)
{
m_Socket.async_receive(boost::asio::buffer(recieveBuffer, TCPClient::maxBufLen),
boost::bind(&TCPClient::onReceive, this, boost::asio::placeholders::error));
}
else
{
cout << "onSend closing" << endl;
cout << "ERROR! onSend..." << ErrorCode << endl;
doClose();
}
}
void TCPClient::onReceive(const boost::system::error_code& ErrorCode)
{
cout << "Msg has been received..." << endl;
if (ErrorCode == 0)
{
cout << recieveBuffer << endl;
cout << "msg length: " << strlen(recieveBuffer) << endl;
//unlock buffer
recieveBuffer[0] = '\0';
}
else
{
cout << "ERROR! onReceive..." << ErrorCode << endl;
doClose();
}
}
void TCPClient::doClose()
{
m_Socket.close();
}
int main()
{
try
{
boost::asio::io_service IO_Service;
tcp::resolver Resolver(IO_Service);
tcp::resolver::query Query("127.0.0.1", "1");
tcp::resolver::iterator EndPointIterator = Resolver.resolve(Query);
TCPClient Client(IO_Service, EndPointIterator);
boost::thread ClientThread(boost::bind(&boost::asio::io_service::run, &IO_Service));
ClientThread.join();
Client.close();
}
catch (exception& e)
{
cerr << e.what() << endl;
}
cout << "\nClosing";
getch();
}
In 'onConnect' completion-handler you call promptTxMsgLoop
that performs an infinite while
loop, so you actually never let io_service
to continue its work -- thus no completion handlers will be invoked anymore. 在'onConnect'完成处理程序中,您调用执行无限while
循环的promptTxMsgLoop
,因此您实际上永远不会让io_service
继续其工作 - 因此将不再调用完成处理程序。
Besides, you call async_send
multiple times, without waiting for the comletion handler of the previous async_send
, which is also incorrect. 此外,您多次调用async_send
,而不等待前一个async_send
的comletion处理程序,这也是不正确的。
Please, see asio documentation to find out correct use patterns. 请参阅asio文档以找出正确的使用模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.