I am implementing protocol with BOOST ASIO which resends response in case it was not acknowledged.
I use async_read_some()
and deadline_timer
running asynchronously alongside
to see whether I received whole message or whether timer expires first and new
message will be sent.
Question is if deadline_timer
expires first how do I close
async_read_some()
and try to read a new message?
Or is there better way to implement protocol which resends messages?
I'm not sure why you want to interrupt async_read_some
if you want to read a new message anyway. There seems to be some flaw (or misunderstanding) in the protocol you are implementing.
This is a question about protocols, not concrete implementation.
The real question is: how do you synchronize sends and reads? Meaning if I send a message to a peer in your network then what is going to happen? Two main ideas are:
Synchronous: when I send a message then it is expected that whatever I read it is going to be the response to that message. In other words the sequence of request response is like this: Req1 -> Resp1 -> Req2 -> Resp2, etc. You could pipe requests as well, i.e. Req1 -> Req2 -> Resp1 -> Resp2. But out of sync responses are not allowed, e.g. this is incorrect: Req1 -> Req2 -> Resp2 -> Resp1. This synchronous approach is widely used in the HTTP protocol.
Asynchronous: with each message I send a unique id and whatever I read is expected to have an id as well. Then I match the response with request by id. With this approach the following sequence is indeed possible: Req1 -> Req2 -> Resp2 -> Resp1.
With the synchronous approach what can you do on timeout? You can still wait for the response and then discard it (with log), but this will delay every other request due to the synchronous nature. And if the peer is nasty this may lead to infinite wait and eventually you will run out of resources. Alternatively you can simply close the connection. This is safer and simpler, and often what devs choose.
With the asynchronous approach you remove the id from your "id-to-response handler map" (which you have to maintain anyway) and that's it. And remember to discard responses without matching id (with log). Of course eventually you want to close nasty connections as well.
The asynchronous approach definitely performs better but is harder to implement correctly.