Discussion:
[asio-users] boost asio: how to improve reliability, when closing socket
avib369 .
2014-10-27 14:38:27 UTC
Permalink
I have a single threaded asynchronous client/server built with boost asio.
In my case I have short lived clients, that send a message to server, and
wait
for response. The client has timer, where I wait for response from the
server,
If the server does not respond in ~80 seconds, then I try again.
This is built on the assumption that If i get a time out, then the server,
never got the message, so I should try again.

In 99.99999% every thinks work ok, however, some times, I get this
behaviour:
- The server receives a request
- it process the request,
- then do a clean shut-down of the connection

conn->socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both);
conn->socket.close()

However the client *never* receives the EOF, it then times out,
and re-sends the same message again.

The net effect being that server process the same request twice. yuk.

I have async read, in the client, so its not clear, why on some very rare
cases, it never
receives the EOF when the server shuts down and closes the socket. (well at
least
not in the specified time period).

I assume this is some form of network glitch, which leaves a half open
connection?

What can I do to prevent, this. I do not want the server, to process the
same request twice.
The only things I can think of are:
1/ Increase the time out period in the client. If so to what ?
2/ After processing the request in the server, do a explicit async
write first, i.e like
message processed in my protocol. Would this be any more robust.
3/ Add some form of 3 way handshake. But doesn’t TCP/IP do this anyway
?

has anyone come across these issues, or found alternative ways to improve
reliability.

Any help appreciated.

Ta,
Avi
Dale Wilson
2014-10-27 15:59:13 UTC
Permalink
I have a single threaded asynchronous client/server built with boost asio.
In my case I have short lived clients, that send a message to server,
and wait
for response. The client has timer, where I wait for response from the
server,
If the server does not respond in ~80 seconds, then I try again.
This is built on the assumption that If i get a time out, then the server,
never got the message, so I should try again.
This is not a completely valid assumption. The close notification could
be on the way delayed by any number of things.
However, I guess you already know that.

<SNIP>
However the client *never* receives the EOF, it then times out,
and re-sends the same message again.
The net effect being that server process the same request twice. yuk.
What can I do to prevent, this. I do not want the server, to process
the same request twice.
1/ Increase the time out period in the client. If so to what ?
2/ After processing the request in the server, do a explicit async
write first, i.e like
message processed in my protocol. Would this be any more robust.
I would do this anyway. As it stands the client has no way to
distinguish between
"Everything is fine so I closed the socket" and
"Something went terribly wrong so I closed the socket."
3/ Add some form of 3 way handshake. But doesn’t TCP/IP do this anyway ?
4 Add a serial number to the request, and have the server remember the
last request processed from this client.
If it receives a request with the same (or lower) serial number it can
simply log that fact and ignore the request.
(there are a lot of assumptions here -- in particular it assumes that
each client has a recognizable identity.)

Dale
--
Dale Wilson
Principal Software Engineer
Object Computing, Inc.
Loading...