boost asio async_read_some reading only pieces of data

boost, boost-asio, c++

Solution

Your code does what it is supposed to do - it reads as much data as it can. This is why the function `async_read_some` name ends with "some" - it reads "some" bytes and does not promise to do more than that. Documentation also says the following:

Consider using the async_read function if you need to ensure that the requested amount of data is read before the asynchronous operation completes.

Which seems like your case unless you re-work your receiver to handle partial reads.

Problem

i have a c++ server which is using boost::asio to do read/write operations - writing out the messages works fine - yet for some reason i cannot get the read to work the message i am sending to it from the client is 15 16 bit unsigned shorts - my test message is this: ``` 1, 34, 7, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0 ``` now on the server i'm seeing things like this constantly. the read is often broken up and/or multiplied by 256 this is one run sending it twice ``` reading length = 8: [1 34 7 0 0 0 0 0] reading length = 3: [1024 0 0] reading length = 3: [0 0 0] reading length = 8: [1 34 7 0 0 0 0 0] reading length = 6: [1024 0 0 0 0 0] ``` this is the second run sending it twice ``` reading length = 8: [1 34 7 0 0 0 0 0] reading length = 6: [1024 0 0 0 0 0] reading length = 6: [1 34 7 0 0 0] reading length = 1: [0] reading length = 0: [] reading length = 0: [] reading length = 2: [0 0] reading length = 2: [0 0] reading length = 1: [0] ``` this is the third run sending it once (i don't know what happened here) ``` reading length = 14: [256 8704 1792 0 0 0 0 0 1024 0 0 0 0 0] ``` Here is the actual server read code ``` void Session::start(void) { msg_interface->add_msg_listener(this); _socket.async_read_some( boost::asio::buffer(_read_data_buffer, READ_DATA_BUFFER_LENGTH), boost::bind(&Session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void Session::handle_read(const boost::system::error_code& error, std::size_t bytes_transferred) { if (error) { msg_interface->remove_msg_listener(this); delete this; } else { if (bytes_transferred != 0) { // print what we've received const int length = bytes_transferred / sizeof(uint16_t); std::cout << "reading length = " << length << ": ["; for (int i = 0; i < length; i++) { const uint16_t data = ntohs(_read_data_buffer[i]); std::cout << data; if (i != length - 1) { std::cout << " "; } } std::cout << "]" << std::endl; } _socket.async_read_some( boost::asio::buffer(_read_data_buffer, READ_DATA_BUFFER_LENGTH), boost::bind(&Session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } } ``` the variables are as follows ``` const int READ_DATA_BUFFER_LENGTH = 1024; class AbstractSession { protected: uint16_t _read_data_buffer[READ_DATA_BUFFER_LENGTH]; ... ``` There is one thing - i am using the same IO service to write messages when they are received (the server is talking to an old interface and sends out the messages it receives to all the clients) and to read messages from the clients. could using the same io service for both cause this to happen? Any thoughts on what i should do to fix this?

Original source