Re: TCP Socket keepalive

Haitao Zhang <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <CAFUyvhp4mj8OwR+fL5AETdcbHF6iZfSxgL1ReRt07Uh5wNtVmg@mail.gmail.com>
Hi Jeff,

Thanks for the explanation. What is interesting in my case is that the tcp
connection was definitely established. I intend it to be a long session (it
connects to a 127.0.0.x port to talk a local service), but it sometimes
loses the connection due to inactivity (more on this later). At such times
a write to the stream would raise an error, which is expected. What is
surprising is that close(Stream) also raises an error. My guess is that the
underlying stream has already been closed by the native socket library
unbeknownst to Prolog (I am on Windows), so both actions raise the same
WSAENOTSOCK error (I traced that far by grepping the "Socket operation on
non-socket" message). I am okay with it although I would have expected
close/1 to intercept the exception in this case, since there is a well
defined semantics here (close(close()) == close() idempotent?).

Now back to the original issue of keeping the connection, it seems that TCP
keepalive should really be used to detect failed connections and release
resources. TCP connection should not expire unless explicitly released.
What happened was: if my computer goes to sleep, after waking up the Prolog
client can send one packet successfully, but fails on the second attempt.
So it looks like some socket internal stuff fell out of sync. But the
server is unaware of this so it is not a reset from the server side.
Subsequently I can reconnect but open threads are piling up on the server
side. So I implemented tcp keepalive on the server side to get rid of dead
connections. Interestingly now the Prolog client side starts to fail sooner
-- I assume after the connection being idle for two hours the server side
starts sending keepalive packets to the client side and the client side
somehow shuts down the socket in response. Now all of these could be
completely internal to the winsock library so Prolog would have no control
over it, but I really can't tell.

It seems that most people recommend application level keep-alive if one
wants to keep a connection around.



On Wed, Dec 11, 2013 at 4:48 PM, Jeff Rosenwald <[email protected]> wrote:

> Hi Haitao:
>
> Supposing that your client looks something like this:
>
> client_stream(IPAddress, In, Out) :-
>   tcp_socket(S),
>   tcp_connect(S, IPAddress, In, Out).
>
> If client_stream/3 succeeds then In and Out will be unified with the
> appropriate Prolog streams. If it succeeds, then safety requires that
> you eventually close both streams using "close(Stream, [force(true)])," and
> you must not release the socket via tcp_close_socket/1 since it is no
> longer valid.
>
> BUT, it is perfectly reasonable to expect that occasionally the above will
> throw an exception due the failure to connect. In that case you *must not*
> close the streams since they are unbound and you must release the socket
> using tcp_close_socket/1. If you don't then the socket is leaked.
>
> Your client_stream/3 needs to look something like:
>
> client_stream(IPAddress, In, Out) :-
>         setup_call_catcher_cleanup(tcp_socket(Socket),
>                                    tcp_connect(Socket, IPAddress, In, Out),
>                                    exception(_),
>                                    tcp_close_socket(Socket)).
>
> (Code not tested)
>
> Please see Section 6.2 of the clib docs to see how the socket should be
> managed at this critical time.
>
> Regards,
> Jeff R.
>
>  -----Original Message-----
> From: Haitao Zhang <[email protected]>
> To: Jan Wielemaker <[email protected]>
> Cc: swi-prolog <[email protected]>
> Sent: Wed, Dec 11, 2013 3:08 am
> Subject: Re: [SWIPL] TCP Socket keepalive
>
> Hi Jan,
>
> Thanks for the response. I will take a look at tcp_setopt/setsockopt.
>
> On a related note, after the send error (as the socket closed unexpectedly)
> if I call close/1 on the stream, I get the same error. Now that is a little
> confusing. Shouldn't close/1 just silently ignore the error?
> tcp_close_socket on the other hand seems to gracefully handle the
> situation. When I close down a channel, should I
>
> A) just call tcp_close_socket on the socket, and don't call close on the
> stream?
>
> or
>
> B) do both, but wrap the close on the stream to trap the error condition?
> It seems weird that one needs to wrap the close/1 since it should be in the
> cleanup clause of an exception handler.
>
> Haitao
>
>
> On Tue, Dec 10, 2013 at 12:57 AM, Jan Wielemaker <[email protected]> wrote:
>
> > On 12/10/2013 08:26 AM, Haitao Zhang wrote:
> >
> >> I have a problem with the TCP socket, where SWI Prolog is client,
> >> disappearing after some time (presumably some inactivity timer expired). I
> >> have set my server side to keepalive, but that does not seem to help.
> >>
> >> The message I get from trying to use the socket again after a long idle
> >> time:
> >> ERROR: format/3: I/O error in write on stream <stream>(000000000834B260)
> >> (Socket operation on non-socket)
> >>
> >> Any idea on how keep the socket alive?
> >>
> >
> > There is tcp_setopt/2, which binds to setsockopt().  It doesn't support
> > the SO_KEEPALIVE option yet.  Should be easy enough to add.  If you use
> > a source version, see packages/clib.  Try it and submit a patch with
> > additional options you see fit.
> >
> >         Hope this helps
> >
> >                 --- Jan
> >
> >
> >
> >> Thanks,
> >> Haitao
> >> -------------- next part --------------
> >> HTML attachment scrubbed and removed
> >> _______________________________________________
> >> SWI-Prolog mailing list
> >> [email protected]
> >> https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
> >>
> >>
> >
> -------------- next part --------------
> HTML attachment scrubbed and removed
> _______________________________________________
> SWI-Prolog mailing [email protected]://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
>
>
-------------- next part --------------
HTML attachment scrubbed and removed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.