Subject | Re: [firebird-support] Immediate Detection of Disconnected Clients on Classic |
---|---|
Author | Tomasz Tyrakowski |
Post date | 2017-04-27T16:08:07Z |
On 25.04.2017 o 17:03, hvlad@... [firebird-support] wrote:
most readers) explanation, but skpping the details: when a TCP
connection (a socket) is closed "normally", there's some handshaking
performed between the endpoints (FIN and FIN ACK packets being
exchanged). And in that case a TCP socket can detect "immediately" that
the other party has just closed its socket.
Another scenario: the client simply crashes without properly closing its
socket and the client OS reclaims the resources. As soon as the server
(which doesn't know yet that there is no client app any more) tries to
send a packet to a nonexistent client socket, it gets a response from
the client OS (not the client app - there is none), that the endpoint is
invalid (a RST packet, followed by a SYN-RST sequence, if I remember
correctly, but that's irrelevant). That's another case when the server
can detect the client failure, but the detection takes place at the
moment of the next data transmission to the client (and there might be
none for quite a long time - unless the server does some kind of
heartbeat with all its clients).
However, when you have a client - server connection, and the packets
travel via many routers in between, and one of the routers fail, there's
just no traffic going either way (no FIN, ACK, RESET packets get
through). In this case neither side knows what's going on - is there a
network failure, has the other side crashed, or just the network got
really slow. The server sends some data and nothing comes back (neither
ACK nor RESET), so the TCP protocol retries the transmission after some
time (again no response), it tries again etc., and after the final
timeout (which is implementation-dependent) it considers the connection
to be unusable and closes the socket (and that's the moment the server
process gets notified).
If you've started to yawn in the middle of my argument, don't worry -
I'm used to that ;) Just wanted to point out there's no magic in TCP and
if you partition the network and no control packets can be exchanged,
there's no way you can detect what really happened. So let's not blame
Firebird for keeping open connections to dead clients for some time,
that's not its fault.
regards
Tomasz
--
__--==============================--__
__--== Tomasz Tyrakowski ==--__
__--== SOL-SYSTEM ==--__
__--== http://www.sol-system.pl ==--__
__--==============================--__
> [...]OK, that would require another rather lengthy (and probably boring for
> I don't actually think Firebird can detect client disconnection
> "immediately" when there is no data exchange between the server and the
> client (it would require some kind of heartbeat increasing traffic and
> would be based on timeouts, which are tricky), otherwise byzantine
> network partitions wouldn't be so nasty.
>
>
> Firebird can do it even if there is no data exchange because it always listens all
> known client socket. When OS closed socket it is detected by Firebird listener.
>
> Regards,
> Vlad
most readers) explanation, but skpping the details: when a TCP
connection (a socket) is closed "normally", there's some handshaking
performed between the endpoints (FIN and FIN ACK packets being
exchanged). And in that case a TCP socket can detect "immediately" that
the other party has just closed its socket.
Another scenario: the client simply crashes without properly closing its
socket and the client OS reclaims the resources. As soon as the server
(which doesn't know yet that there is no client app any more) tries to
send a packet to a nonexistent client socket, it gets a response from
the client OS (not the client app - there is none), that the endpoint is
invalid (a RST packet, followed by a SYN-RST sequence, if I remember
correctly, but that's irrelevant). That's another case when the server
can detect the client failure, but the detection takes place at the
moment of the next data transmission to the client (and there might be
none for quite a long time - unless the server does some kind of
heartbeat with all its clients).
However, when you have a client - server connection, and the packets
travel via many routers in between, and one of the routers fail, there's
just no traffic going either way (no FIN, ACK, RESET packets get
through). In this case neither side knows what's going on - is there a
network failure, has the other side crashed, or just the network got
really slow. The server sends some data and nothing comes back (neither
ACK nor RESET), so the TCP protocol retries the transmission after some
time (again no response), it tries again etc., and after the final
timeout (which is implementation-dependent) it considers the connection
to be unusable and closes the socket (and that's the moment the server
process gets notified).
If you've started to yawn in the middle of my argument, don't worry -
I'm used to that ;) Just wanted to point out there's no magic in TCP and
if you partition the network and no control packets can be exchanged,
there's no way you can detect what really happened. So let's not blame
Firebird for keeping open connections to dead clients for some time,
that's not its fault.
regards
Tomasz
--
__--==============================--__
__--== Tomasz Tyrakowski ==--__
__--== SOL-SYSTEM ==--__
__--== http://www.sol-system.pl ==--__
__--==============================--__