Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[ports] [tcp] Detecting peer closing connection

 [1/10] 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/

 [2/10] from: rotenca:telvia:it at: 21-Nov-2003 13:39


Hi Gabriele,
> 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.)
Yesss, async-modes WRITE uses a forever loop which calls awake forever (use only when needed).
> (BTW, I found the strange behavior, and Romano found out the > reason, so all the credit goes to him. :)
You overdo my role :-) Sent to feedback? --- Ciao Romano

 [3/10] from: petr:krenzelok:trz:cz at: 21-Nov-2003 14:08


Gabriele Santilli wrote:
>Hello all, > while doing some tests I and Romano have discovered a strange
<<quoted lines omitted: 10>>
>result is equivalent to NONE, since the AWAKE won't be called if >there's no new data available.
Hello Gabriele, I found one earlier post by Holger, well .... I miss his educative posts so much :-) I don't know if you can find any answers related to your problem there, but maybe someone other will find it quite educative: http://www.escribe.com/internet/rebol/m15313.html
>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). >
As for ports bug in general, I reported some strange behavior some time ago. Win98 scenario, Rebol (don't remember what version), and our device (8bit chip ethernet + tcp implementation). When we opened port in open/direct/no-wait, followed by following loop: while [wait port data: copy port][...], it simply escaped the loop and in Ethereal we could see PC lowered tcp window to 0 and PC sent RST packet then. Yes, we could tell that 8bit Scenix chip tcp implementation could be flawed, but the case was solved by simple adding /binary refinement - so - should open/direct/no-wait and open/direct/no-wait/binary behave differently? The rest of the code stayed unchanged. Why without /binary refinement wait loop was escaped? Could it be related to none vs #{} issue you describe? The bug was not confirmed by RT and who knows if it is even a bug, although it seems so. I would have to check with latest Rebol releases if it is still the same ... Cheers, -pekr-

 [4/10] from: g::santilli::tiscalinet::it at: 21-Nov-2003 14:18


Hi Romano, On Friday, November 21, 2003, 1:39:23 PM, you wrote: RPT> Sent to feedback? No... would you think it's a bug? Anyway, maybe it's better to send it... Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/

 [5/10] from: g:santilli:tiscalinet:it at: 21-Nov-2003 14:37


Hi Petr, On Friday, November 21, 2003, 2:08:32 PM, you wrote: PK> http://www.escribe.com/internet/rebol/m15313.html "You can detect whether your receive pipe has been closed by the peer by performing a 'copy on the port, assuming the port is in /no-wait mode. A none return means the other side has closed its send pipe (your receive pipe), any other value means that your receive pipe is still open." This means I can assume that the behavior we have observed is a bug? PK> case was solved by simple adding /binary refinement - so - should PK> open/direct/no-wait and open/direct/no-wait/binary behave differently? I don't think it should in your case, but maybe the code in REBOL that translates line terminators was interfering somehow? Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/

 [6/10] from: maarten:vrijheid at: 21-Nov-2003 14:37


Hi Gabriele, I think this may have to do with the port being in async mode? Or did you test it in sync mode as well? --Maarten

 [7/10] from: g:santilli:tiscalinet:it at: 21-Nov-2003 15:02


Hi Maarten, On Friday, November 21, 2003, 2:37:06 PM, you wrote: MK> I think this may have to do with the port being in async mode? Or did MK> you test it in sync mode as well? I tested it in sync mode only. I think that Romano tried in async mode too. Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/

 [8/10] from: g:santilli:tiscalinet:it at: 21-Nov-2003 15:22


Hello all, this is an example of the problem (I'm sending it to feedback too): ====8<====Console 1=========8<=============8<=============8<>> l: open/binary/no-wait tcp://:10000
>> p: first l >> insert/dup p "bla bla " 100 >> copy p
== #{74657374}
>> copy p
== #{}
>> copy p
== #{}
>> copy p
== #{}
>> copy p
== #{}
>> close p
====>8======================>8=============>8=============>8====== ====8<====Console 2=========8<=============8<=============8<>> p: open/binary/no-wait tcp://localhost:10000
>> insert p "test" >> close p
====>8======================>8=============>8=============>8====== COPY correctly returns NONE if the port send buffer is empty. Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/

 [9/10] from: rotenca:telvia:it at: 21-Nov-2003 15:42


Hi Maarten,
> I think this may have to do with the port being in async mode? Or did > you test it in sync mode as well?
It is the same. But in async mode, copy should not be used, you must use read-io, and read-io in this case returns 0 instead of < 0. --- Ciao Romano

 [10/10] from: greggirwin:mindspring at: 21-Nov-2003 9:50


Hi Gabriele, GS> I think this issue is the reason why some people (Gregg?) had GS> problems with async:// when peer closed the connection. I remember that. I never looked into, but it could relate to how they handle underlying ports that are half-closed. I remember half-closed ports as being something you had to consider when I did some winsock stuff some time back. -- Gregg

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted