I try to send a large data (1mb+) from a server to a client using the boost's asio library.
I split the data into chunks of size 16000 and use async_write_some to send them. I read the data with async_read or async_read_some in the client.
When both the server and the client are my local machine, everything works fine and I can send 10mb+ data without any problems.
When I use a different machine to send the data it is ok with data less than 1mb. but when the data size is 1mb+ there is a data loss between chunks when the client reads it. I am using an ethernet cable to connect the server and the client (the network is really reliable).
When I put a timeout between sending chunks like:
std::this_thread::sleep_for(30ms)
The client could get the whole data without any loss.
Could somebody give me some hints what is happening and how can I correct mistakes? TCP requires that no data lost must be occurred in any situation.
Edit: Here is the send logic
void SendData(const char* data, int size) {
const int tr_size = std::min(CHUNK_SIZE, size);
socket_->async_write_some(asio::buffer(data, tr_size),
[this, data = data + tr_size, size = size - tr_size]
(const std::error_code &error, size_t bytes_transferred){
if(!error && size > 0) {
SendData(data, size);
} else if(socket_ && socket_->is_open()) {
socket_->close();
}
});
}
Here is the receive logic
void ReceiveData(char* data, size_t size)
{
socket_.async_read_some(asio::buffer(data, size), [this, data, size]
(const std::error_code &error, size_t bytes_transferred) mutable{
if(!error) {
assert(size >= bytes_transferred);
size -= bytes_transferred;
data += bytes_transferred;
}
if(error) {
return;
}
if(size > 0) {
ReceiveData(data, size);
}
});
tcpis just a byte stream -- no packets as such. So there's no guarantee a write at one end will correspond to exactly one read at the other end. - G.M.SendDataimplementation seems to assume thatasync_write_somealways writes the specified number of bytes (tr_sizein this case) before the handler is called. - G.M.bytes_transferredin your send lambda. How do you know how many bytes were sent? Also see the remark at the bottom of the async_write_some documentation. - rustyxasync_write_somewas the problem. Replacing it withasync_writesolved the problem. Thank you for noticing it. - asmbaty