Boost logo

Boost Users :

Subject: Re: [Boost-users] Synchronous problem with asio
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2009-08-11 08:34:38


2009/8/11 Dan Benèík <eubie_at_[hidden]>:
> 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_at_[hidden]
> 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 :)


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net