From: Zelphir Kaltstahl <zelphirkaltstahl@gmail.com>
To: guile-user@gnu.org
Subject: Re: Re: How to notice abrupt tcp connection losses in server/client?
Date: Fri, 22 Jun 2018 00:19:49 +0200 [thread overview]
Message-ID: <197dbcf5-97f0-aab9-87b4-cbf61321adab@gmail.com> (raw)
In-Reply-To: <mailman.115.1529596820.18527.guile-user@gnu.org>
On 21.06.2018 18:00, guile-user-request@gnu.org wrote:
> Message: 5
> Date: Thu, 21 Jun 2018 16:08:20 +0100
> From: Chris Vine <vine35792468@gmail.com>
> To: guile-user@gnu.org
> Subject: Re: How to notice abrupt tcp connection losses in
> server/client?
> Message-ID: <20180621160820.1359196e2d30873d4a3cc1e4@gmail.com>
> Content-Type: text/plain; charset=US-ASCII
>
> On Thu, 21 Jun 2018 08:22:36 +0200
> Zelphir Kaltstahl <zelphirkaltstahl@gmail.com> 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
next parent reply other threads:[~2018-06-21 22:19 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <mailman.115.1529596820.18527.guile-user@gnu.org>
2018-06-21 22:19 ` Zelphir Kaltstahl [this message]
2018-06-21 23:09 ` How to notice abrupt tcp connection losses in server/client? Chris Vine
2018-06-22 6:27 ` Eli Zaretskii
2018-06-22 10:07 ` Chris Vine
[not found] <mailman.107.1529683219.32327.guile-user@gnu.org>
2018-06-22 20:17 ` Zelphir Kaltstahl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=197dbcf5-97f0-aab9-87b4-cbf61321adab@gmail.com \
--to=zelphirkaltstahl@gmail.com \
--cc=guile-user@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).