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: Fri, 22 Jun 2018 00:09:16 +0100

On Fri, 22 Jun 2018 00:19:49 +0200
Zelphir Kaltstahl <address@hidden> wrote:
> On 21.06.2018 18:00, address@hidden wrote:
> > From: Chris Vine <address@hidden>
[snip]
> > 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.

It looks as if recv! returns 0 on end-of-file, not an eof-object, so
that may be your problem.  That is not the case with get-line or
get-bytevector-n.  Note that recv! may also return less than the
requested number of bytes - it does not guarantee to block until the
entire request has been met or end-of-file is reached, as it is just a
wrapper for POSIX/windows recv().

I think you will need to use recv! with windows, because you cannot
read from sockets in windows using POSIX read().  With other OS's it
would be more normal to use the R5RS/R6RS port procedures, because they
are easier to use and are buffered.

For asynchronous non-blocking ports, I am not sure whether recv! is safe
with guile-2.2's suspendable ports or not.  The get-line and
get-bytevector-n procedures are.  The get-bytevector-n! procedure is
not.  I suspect recv! may not be also.

> > 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.

A call to unix read() on a socket is equivalent to a call to recv()
with default flags.  At the end of it, the buffered guile port reading
procedures generally involve a call to read().

> > 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!

The guile-a-sync/guile-a-sync2 libraries (of which I am the author) have
an example of a client and server in the doc directory, which might be
of interest to you.  fibers is definitely worth a look also, but is
linux only, and also guile-2.2 only.  I think it also has some examples
(not sure).

Chris



reply via email to

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