1

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.
            }
        });
    }
cpp_hex
  • 603
  • 1
  • 5
  • 7

1 Answers1

1

async_read is documented as:

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)

sehe
  • 374,641
  • 47
  • 450
  • 633
  • 1
    Thanks ! I used async_read_until with delimiter \n and that floats my boat. It has worked like a charm.... Thanks !!! – cpp_hex Jul 20 '22 at 15:13