guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to notice abrupt tcp connection losses in server/client?


From: Chris Vine
Subject: Re: How to notice abrupt tcp connection losses in server/client?
Date: Thu, 21 Jun 2018 16:08:20 +0100

On Thu, 21 Jun 2018 08:22:36 +0200
Zelphir Kaltstahl <address@hidden> wrote:
> Hello Guile users,
> 
> I wrote some TCP server and client in Guile which I have uploaded here:
> 
> https://gitlab.com/zelphir-kaltstahl-projects/guile-scheme-tutorials-and-examples/raw/dev/network-programming/tcp-client.scm
> 
> and here:
> 
> https://gitlab.com/zelphir-kaltstahl-projects/guile-scheme-tutorials-and-examples/raw/dev/network-programming/tcp-server.scm
> 
> or normal GitLab view:
> 
> https://gitlab.com/zelphir-kaltstahl-projects/guile-scheme-tutorials-and-examples/tree/dev/network-programming
> 
> (Is it OK to post these as links, or always better to include all
> relevant source code on the mailing list? On other e-mail lists I have
> experienced that my message was too long and got truncated, so I posted
> the code as links to the raw file on GitLab.)
> 
> The loop for reacting on messages from a client on the server looks like
> this:
> 
> (while #t
>   (let* ([bytes-count (recv! in-out-sock receive-buffer)]
>          [message-received (byte-vector->utf8-message receive-buffer 
> bytes-count)])
>     (message-handler client-connection message-received))))))
> 
> But this has a problem: When I run both client and server in two
> terminals and then exit the client using Ctrl-D, the server somehow gets
> stuck in the loop always receiving the empty string. Since that is 0
> Bytes long, it does not really take anything from the socket (if I
> understand correctly), but instead can recv! in the next iteration again
> immediately. The only thing that works then for stopping this loop is to
> hold down Ctrl-C on the server for a second or so.
> The same happens for the client receiving message loop, because that one
> also does not detect me suddenly interrupting or killing the server and
> then loops on the empty string.
> At first I thought if I caught eof-object? and then (break) the loop it
> would solve the problem, but apparently it does not.
> Basically I would like the server and client to be prepared for non
> proper shutdown of either.
> 
> How can I handle / detect abrupt connection losses, so that I can break
> the message handling loop?

The POSIX recv() function returns 0 on end of file (connection closed)
so I expect the scheme recv! procedure does the same.  So on end-of-file
your code appears to be producing an endless supply of empty strings.

More generally, you will find it easier to use something like the
get-line procedure to read text, or something like get-bytevector-n or
get-bytevector-n! for reading binary records.  recv! only really becomes
important when the flags argument is meaningful.

Rather than starting a new thread for each connection, you will get much
better scalability if you use something like fibers
( https://github.com/wingo/fibers/ ), guile-a-sync2
( https://github.com/ChrisVine/guile-a-sync2/ ) or 8sync
( https://www.gnu.org/software/8sync/ ).

Chris



reply via email to

[Prev in Thread] Current Thread [Next in Thread]