This is my server session code that should read the incoming client data asynchronously. I am using a free standing read function. When I tested this using Google Test(using local host, and both client and server on same computer), it worked fine. I was able to connect to server using my test client and server used to establish connection and read the data coming from client.
But when I tested in client and server running on different computers, I observed that after connection is established, Server only receives first of the N data items sent by client. And that too when client disconnects after it has finished writing.
My head is spinning and I am not able to find out why. Any help is much appreciated.
Thanks
void ServerSession::doRead()
{
asio::async_read(socket_, asio::buffer(data_,maxLength),
[this](std::error_code ec, std::size_t length)
{
if(!ec || ec == asio::error::eof)
{
std::string msg{data_, length};
addMessageToQueue(std::move(msg));
}
else
{
socket_.close(); //force close the socket upon read error.
}
});
}
This function is used to asynchronously read a certain number of bytes of data from a stream. It is an initiating function for an asynchronous operation, and always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
- The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
- An error occurred.
Apparently neither condition is satisfied until the client disconnects (which satisfies the criteria with the asio::error::eof
error code).
Usually you need to
use an application protocol with framing (such as \r\n\r\n
, Content-Length
or chunked encoding for HTTP) and an CompletionCondition that expresses that. You can also use one of the overloads of async_read_until
which allows some common completion conditions.
Alternatively you can reduce the maxLength
to be practically much smaller than the expected payload so you will likely get an earlier completion
Finally you can "de-optimize" by using the lowlevel AsyncReadStream
operation async_read_some
directly. As e.g. the documentation for tcp::socket::async_read_some
highlights, this is rarely what you want:
The read operation may not read all of the requested number of bytes. Consider using the async_read function if you need to ensure that the requested amount of data is read before the asynchronous operation completes)