guile-user
[Top][All Lists]
Advanced

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

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


From: Zelphir Kaltstahl
Subject: Re: Re: How to notice abrupt tcp connection losses in server/client?
Date: Fri, 22 Jun 2018 00:19:49 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0

On 21.06.2018 18:00, address@hidden wrote:
> Message: 5
> Date: Thu, 21 Jun 2018 16:08:20 +0100
> From: Chris Vine <address@hidden>
> To: address@hidden
> Subject: Re: How to notice abrupt tcp connection losses in
>       server/client?
> Message-ID: <address@hidden>
> Content-Type: text/plain; charset=US-ASCII
>
> 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.
I actually tried to (break) the loop when the received message is
(eof-object? ...), but it might be that I used this predicate at the
wrong place (directly inside the loop when the message was already
copied from the receive-buffer, instead of when recv!, I believe), now
that I think about it … and maybe that is why (break)ing the loop did
not work. Need to investigate more.
> 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.
Ah ok, thanks for the advice! I thought recv! was the way to go, as it
worked so nicely so far.
> 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/ ).
Yep =) I am aware. I already wrote a comment inside the code noting that
this new thread thing is probably not so good. Not sure I should
introduce fibers into this example code yet though. And looking at
fibers and 8sync is on my to-do list ; )
> Chris
I will try these things and see how it goes. Thanks!

~ Zelphir


reply via email to

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