I start only async_read_some() directly after the connection was established.
During the callback I process the received data and then start async_read_some() again.
For the write part:
I'm calling async_write as soon as there is the first data packet to write. While one packet is written no other data can be written, therefore I also use a queue for data to write.
Some pseudo code:
Connection::sendBytes(bytes)
{
if (!sendInProgress) {
socket->async_write_some(bytes, onMessageWritten);
sendInProgress = true;
}
else writeQueue.push_back(bytes);
}
Connection::onBytesWritten()
{
if (writeQueue.size() == 0) {
sendInProgress = false;
}
else {
// Here you can theoretically send all left data at once (using vectored IO) or only some of the data.
// Depending on data size performance will be different.
socket->async_write_some(writeQueue, onBytesWritten);
writeQueue.clear();
}
}
Additionally you will need some error handling and depending on who can call the write methods also locking. If you only do write calls from within a single thread which is driving the io_service then this is much easier because then all reads and writes happen in the same thread (event loop) and you don't locking. E.g. this would be the case if you call sendBytes in your onBytesReceived handler.