[REBOL] [ports] [tcp] Detecting peer closing connection
From: g:santilli:tiscalinet:it at: 21-Nov-2003 12:22
Hello all,
while doing some tests I and Romano have discovered a strange
behavior in REBOL TCP ports. I thought that, when the peer closes
the TCP connection, you got NONE returned by COPY on the TCP port;
however, it is not always so.
We have discovered that, if there's data in the port output
buffer, and the port is in binary mode, when the peer closes teh
connection you'll get an empty binary (#{}) instead of NONE as the
result of COPY.
This way it becomes difficult to know that the connection was
closed (because empty data also means "no new data available"). If
you are using PORT/AWAKE, however, you can assume that an empty
result is equivalent to NONE, since the AWAKE won't be called if
there's no new data available.
Basically, if your PORT/AWAKE is like this:
port/awake: func [port /local data] [
data: copy port
either data [
do-something-with data
] [
; peer closed connection
close port
; remove it from wait list, etc.
]
]
it won't work if the port, at the time the peer closes the
connection, has data in the send buffer.
You'll have to use, instead:
port/awake: func [port /local data] [
data: copy port
either any [none? data empty? data] [
; peer closed connection
close port
; remove it from wait list, etc.
] [
do-something-with data
]
]
that seems to work in every case. (Note: won't work if you have
ASYNC-MODES set to 'WRITE, since then the AWAKE would be called
even if no data is in the receive buffer.)
I think this issue is the reason why some people (Gregg?) had
problems with async:// when peer closed the connection. I'll fix
my version of async:// soon (but becomes a bit complicated because
of the WRITE async mode).
(BTW, I found the strange behavior, and Romano found out the
reason, so all the credit goes to him. :)
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/