Reputation: 51
The implementation:
The client uses async_write to sending messages to the server. In the write handler, it starts next async_write operation.
The server uses async_read to receive messages from the client. In the read handler, it starts next async_read operation.
I want to stop the async operation immediately when the remote side is closed.
When I close the client, the async_read calls the handler immediately with an boost::asio::error::eof error code. But when the server is closed, the client continues writing. How can I make it call the handler with an error code?
Upvotes: 0
Views: 1187
Reputation: 2240
You read/write, in other words you have a protocol, so add a new flag (message, bit ...) saying that you will close the socket, and close the socket only when that message has been received. Of course your protocol must handle errors.
Upvotes: 0
Reputation: 3613
In simple terms your design should look like this:
Call async_read
When you need to write
Call async_write
Do not call async_write again until the previous async_write call has returned. If you need to call multiple async_write operations, then que your buffers.
Call async_write
callback pull next buffer from que
Call async_write
callback pull next buffer from que
Call async_write
callback pull next buffer from que
By doing this, you're ensuring this only one async_write operating is in effect at all times per socket. Which is how it should be. Do NOT do this.
Call async_write
Call async_write
Call async_write
callback
callback
callback
This is where you run into issues by trying to stop async_write after a read operation has occurred with an error. When async_read returns with an error you no longer have to take extra steps in your async_write operation to cancel concurrent calls.
Call async_read
Call async_write
async_read callback returns with error (do not call async_read again)
async_write returns with error (do not call async_write again)
So when calling async_write check a flag (iswriting) if the flag is true, then push your buffer into your que. When the callback returns, check your que, pull the next buffer and call async_write again. If iswriting is false, then just call async_write instead of pushing it to the que. If your callback returns and your que is finally empty then set iswriting to false again.
This is all pretty straight forward...
Upvotes: 1