Dear everybody, I have a problem using asio. My client/server application requires only synchronous communication. So, using the examples for synchro from the boost homepage, I have set up two procedures to send and receive data. Their code is as follows: void vReceive(tcp::socket & socket, std::string & szDest){ char szTmp_Buf [BUF_LEN + 1]; szDest = ""; std::cout << "Entering vReceive . . ." << std::endl; for (;;){ char szBuf [BUF_LEN]; boost::system::error_code error; uInt uiBytes_Recv = socket.read_some(boost::asio::buffer(szBuf), error); std::cout << " Read " << uiBytes_Recv << " bytes" << std::endl; if (error == boost::asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw boost::system::system_error(error); // Some other error. memcpy((void*) szTmp_Buf, (void*) szBuf, uiBytes_Recv ); szTmp_Buf[ uiBytes_Recv ] = '\0'; szDest += szTmp_Buf; }; std::cout << "Received" << szDest << std::endl; std::cout << "Leaving vReceive . . ." << std::endl << std::endl; }; void vSend(tcp::socket & socket, std::string & szSrc){ std::cout << "Entering vSend . . . " << std::endl; std::cout << "Sending " << szSrc << std::endl; boost::system::error_code ignored_error; boost::asio::write(socket, boost::asio::buffer(szSrc), boost::asio::transfer_all(), ignored_error); std::cout << "Leaving vSend . . . " << std::endl << std::endl; }; These procedures are just wrappers for the lines of code extracted from the boost examples. In my test applications, the client calls vReceive(socket, szDate); vSend(socket, std::string("Chop Suey!") ); vReceive(socket, szDate); vSend(socket, std::string("Halo")); and the server calls vSend(socket, message); vReceive(socket, szReceived); vSend(socket, message); vReceive(socket, szReceived); just to test the functionality. The problem is that both applications freeze after the first information exchange, as I have depicted on the following picture ( http://eubie.sweb.cz/asio_problem.JPG ). It seems that vReceive() procedure on the client side doesn´t finish while vSend() finishes on the server side. So, does anybody have any idea, what might be wrong? Just in case someone wanted to replicate the problem, I uploaded the complete sources to http://eubie.sweb.cz/asio_problem.rar file. Thank you all in advance, Daniel.
for (;;){ char szBuf [BUF_LEN]; boost::system::error_code error; uInt uiBytes_Recv = socket.read_some(boost::asio::buffer(szBuf), error); std::cout << " Read " << uiBytes_Recv << " bytes" << std::endl; if (error == boost::asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw boost::system::system_error(error); // Some other error.
memcpy((void*) szTmp_Buf, (void*) szBuf, uiBytes_Recv ); szTmp_Buf[ uiBytes_Recv ] = '\0'; szDest += szTmp_Buf; };
You receive function looks like it never exits -- until some error occurs or the socket is closed. Was this the intent (or am I missing something)?
2009/8/11 Dan Benčík
Dear everybody, I have a problem using asio. My client/server application requires only synchronous communication. So, using the examples for synchro from the boost homepage, I have set up two procedures to send and receive data. Their code is as follows:
void vReceive(tcp::socket & socket, std::string & szDest){ char szTmp_Buf [BUF_LEN + 1]; szDest = ""; std::cout << "Entering vReceive . . ." << std::endl;
for (;;){ char szBuf [BUF_LEN]; boost::system::error_code error; uInt uiBytes_Recv = socket.read_some(boost::asio::buffer(szBuf), error); std::cout << " Read " << uiBytes_Recv << " bytes" << std::endl; if (error == boost::asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw boost::system::system_error(error); // Some other error.
memcpy((void*) szTmp_Buf, (void*) szBuf, uiBytes_Recv ); szTmp_Buf[ uiBytes_Recv ] = '\0'; szDest += szTmp_Buf; }; std::cout << "Received" << szDest << std::endl; std::cout << "Leaving vReceive . . ." << std::endl << std::endl; };
void vSend(tcp::socket & socket, std::string & szSrc){ std::cout << "Entering vSend . . . " << std::endl; std::cout << "Sending " << szSrc << std::endl; boost::system::error_code ignored_error; boost::asio::write(socket, boost::asio::buffer(szSrc), boost::asio::transfer_all(), ignored_error); std::cout << "Leaving vSend . . . " << std::endl << std::endl; };
These procedures are just wrappers for the lines of code extracted from the boost examples.
In my test applications, the client calls
vReceive(socket, szDate); vSend(socket, std::string("Chop Suey!") ); vReceive(socket, szDate); vSend(socket, std::string("Halo"));
and the server calls
vSend(socket, message); vReceive(socket, szReceived); vSend(socket, message); vReceive(socket, szReceived);
just to test the functionality. The problem is that both applications freeze after the first information exchange, as I have depicted on the following picture ( http://eubie.sweb.cz/asio_problem.JPG ). It seems that vReceive() procedure on the client side doesn´t finish while vSend() finishes on the server side. So, does anybody have any idea, what might be wrong?
Just in case someone wanted to replicate the problem, I uploaded the complete sources to http://eubie.sweb.cz/asio_problem.rar file.
Thank you all in advance, Daniel. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
You're using boost::asio::write() to overcome the limitation of socket.send() that it might not send all the data in one pass, so why not do the same for reading? Instead of making the loop yourself, just use boost::asio::read(). Furthermore, you don't need to use the completion condition version with transfer_all(), you can use the alternate overload, which automatically does that for you. boost::asio::write(socket_, boost::asio::buffer(szOutput, szOutput.length())); boost::asio::read(socket_, boost::asio::buffer(szInput, szInput.length())); Short and sweet, that's all you need :)
Dear Zachary,
thank you VERY MUCH. You can't imagine how much time I spent looking for an answer as simple as the one of yours! Finally my code works:)
All the best,
Daniel.
< ------------ Původní zpráva ------------
< Od: Zachary Turner
participants (3)
-
Dan Benčík
-
Igor R
-
Zachary Turner