Boost logo

Boost Users :

Subject: Re: [Boost-users] [ASIO] Wrong usage of streambuf ?
From: Imran Fanaswala (imran.fanaswala_at_[hidden])
Date: 2009-12-11 00:46:23


> Date: Tue, 08 Dec 2009 15:03:46 +0100
> From: Axel <axel.boost_at_[hidden]>
> To: boost-users_at_[hidden]
> Subject: [Boost-users] [ASIO] Wrong usage of streambuf ?
> Message-ID: <4B1E5CC2.6040103_at_[hidden]>
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
>  Hello
>
> I m writing a simple client/server program. On a request the server
> answers "ok\r\n". It works well. I have a problem with the client.
> Using async functions, I don't manage to handle the response from the
> server. Once the server sent the response, I want to read the data,
> close the socket, and open a new connection to the server.
>
> When I don't read the data sent by the server, I manage to close the
> socket and repeat the operation (close the socket, and reconnect to the
> server).
> When I read the data, the program seems to block.
>
> /* Callback to the async_write function. On any request, the server
> sends "ok\r_n" */
> void Client::handle_write(boost::asio::ip::tcp::socket* socket, const
> boost::system::error_code& err)
> {
>     if(!err)
>     {
>         cout << "Read..." << endl ;
>     // response_ is a boost::asio::streambuf variable
>         boost::asio::async_read_until(*socket, response_, "\r\n",
> boost::bind(&Client::handle_read, this, socket,
> boost::asio::placeholders::error,
> boost::asio::placeholders::bytes_transferred)) ;
>     }
>     else
>     {
>         cout << "Error when writing to host: " << err.message() << "\n" ;
>     }
> }
>
> void Client::handle_read(boost::asio::ip::tcp::socket* socket, const
> boost::system::error_code& err, size_t bytes_transferred)
> {
>     cout << bytes_transferred << " bytes received. " << endl ;
>
>     /* Dont count the 2 bytes long "\r\n" string */
>     int message_size = bytes_transferred - 2 ;
>
>
>     char * response_char = new char[message_size + 1] ;
>     response_char[message_size] = '\0' ;
>     response_stream.read(response_char, message_size) ;
>     string result(response_char) ;
>     delete response_char ;
>     response_.consume(2) ;
>
>     socket->close() ;
>     delete socket ;
>     connect() ;
>     return ;
> }
>
> If I skip the block where I read the response_ into a string, the
> program works flawlessly. If I try to read the response from the
> streambuf variable, the program is blocked at the next call to
> async_read_until() */
> So I guess that I m doing something wrong with the streambuf variable
> named "response_", but I dont understand what. Can someone explain me
> what is wrong ?
>
> Thanks in advance.
>

I am not really sure what response_stream is, but I see what you are
trying to do. Consider doing the following instead:

void Client::handle_read(boost::asio::ip::tcp::socket* socket, const
boost::system::error_code& err, size_t bytes_transferred)
{
...
  //Note: data, will contain the "ok\r\n".. so just do some string
manip to get rid of it
  const char* data=boost::asio::buffer_cast<const char*>(response_.data());

  response_.consume(bytes_transferred); //This is the key...
...
}


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