I'm trying to provoke the Exceptions which Socket>>#waitForDataFor: would
signal on failure (and test that it does so), to no avail (no, the .image isn't locked and the process doesn't hang). The below runs in both the Squeak 3.9,3.8 final .images with both the 3.10.2,3.10.6 VMs on win32; the worker process always terminates without an exception. The implementation of #waitForDataFor: (#waitForDataFor:ifClosed:ifTimedOut:) looks like #dataAvailable returns true but there cannot be any data since nothing was ever sent. *but* after closing the client side, the other side's #dataAvailable (#primSocketReceiveDataAvailable) returns true ... Any hint(s) on what's going on (or wrong) will be recognized with gratitude. /Klaus | localhost serverSocket sessionSocket clientSocket worker | localhost := NetNameResolver localHostAddress. "warning:" Socket allInstancesDo: [:socket | socket destroy]. serverSocket := Socket newTCP listenOn: 7680 backlogSize: 1. clientSocket := Socket newTCP connectNonBlockingTo: localhost port: 7680. sessionSocket := serverSocket waitForAcceptFor: 1. worker := [sessionSocket waitForDataFor: 1] fork. Processor yield. Transcript cr; show: serverSocket statusString, ' [server]'; cr; show: clientSocket statusString, ' [client]'; cr; show: sessionSocket statusString, ' [session], dataAvailable: ' , sessionSocket dataAvailable storeString; cr; show: 'worker: ', worker browserPrintString. [clientSocket close] on: Exception do: [:ex|]. Processor yield. Transcript cr; show: serverSocket statusString, ' [server]'; cr; show: clientSocket statusString, ' [client]'; cr; show: sessionSocket statusString, ' [session], dataAvailable: ' , sessionSocket dataAvailable storeString; cr; show: 'worker: ', worker browserPrintString; cr. [sessionSocket destroy] on: Exception do: [:ex|]. [clientSocket destroy] on: Exception do: [:ex|]. [serverSocket destroy] on: Exception do: [:ex|] |
I think it was done intentionally,
when socket closed , it signals that data available, to awake process which waiting for data. Then, when process tries to read it, it returns 0 bytes. I think it's same as with socket's read() function. If remote side closed gracefully, a blocking read() function returns with 0, indicating that there 0 bytes read, and connection is closed. On 25/02/2008, Klaus D. Witzel <[hidden email]> wrote: > I'm trying to provoke the Exceptions which Socket>>#waitForDataFor: would > signal on failure (and test that it does so), to no avail (no, the .image > isn't locked and the process doesn't hang). > > The below runs in both the Squeak 3.9,3.8 final .images with both the > 3.10.2,3.10.6 VMs on win32; the worker process always terminates without > an exception. > > The implementation of #waitForDataFor: > (#waitForDataFor:ifClosed:ifTimedOut:) looks like #dataAvailable returns > true but there cannot be any data since nothing was ever sent. *but* after > closing the client side, the other side's #dataAvailable > (#primSocketReceiveDataAvailable) returns true ... > > Any hint(s) on what's going on (or wrong) will be recognized with > gratitude. > > /Klaus > > | localhost serverSocket sessionSocket clientSocket worker | > > localhost := NetNameResolver localHostAddress. > "warning:" Socket allInstancesDo: [:socket | socket destroy]. > serverSocket := Socket newTCP listenOn: 7680 backlogSize: 1. > clientSocket := Socket newTCP connectNonBlockingTo: localhost port: 7680. > sessionSocket := serverSocket waitForAcceptFor: 1. > worker := [sessionSocket waitForDataFor: 1] fork. > Processor yield. > Transcript cr; show: serverSocket statusString, ' [server]'; > cr; show: clientSocket statusString, ' [client]'; > cr; show: sessionSocket statusString, ' [session], dataAvailable: ' > , sessionSocket dataAvailable storeString; > cr; show: 'worker: ', worker browserPrintString. > [clientSocket close] on: Exception do: [:ex|]. > Processor yield. > Transcript cr; show: serverSocket statusString, ' [server]'; > cr; show: clientSocket statusString, ' [client]'; > cr; show: sessionSocket statusString, ' [session], dataAvailable: ' > , sessionSocket dataAvailable storeString; > cr; show: 'worker: ', worker browserPrintString; cr. > [sessionSocket destroy] on: Exception do: [:ex|]. > [clientSocket destroy] on: Exception do: [:ex|]. > [serverSocket destroy] on: Exception do: [:ex|] > > > -- Best regards, Igor Stasenko AKA sig. |
On Mon, 25 Feb 2008 16:24:43 +0100, Igor Stasenko wrote:
> I think it was done intentionally, > when socket closed , it signals that data available, to awake process > which waiting for data. Then, when process tries to read it, it > returns 0 bytes. Nothing speaks against such behavior except the method's comment "Wait for the given nr of seconds for data to arrive. Signal a time out or connection close exception if either happens before data becomes available." > I think it's same as with socket's read() function. > If remote side closed gracefully, a blocking read() function returns > with 0, indicating that there 0 bytes read, and connection is closed. So senders of #waitForDataFor: cannot know about closed connections (even if the comment says the opposite) and *must* do at least #receiveSomeData because #waitForDataFor: can't handle all the possible situations? > On 25/02/2008, Klaus D. Witzel wrote: >> I'm trying to provoke the Exceptions which Socket>>#waitForDataFor: >> would >> signal on failure (and test that it does so), to no avail (no, the >> .image >> isn't locked and the process doesn't hang). >> >> The below runs in both the Squeak 3.9,3.8 final .images with both the >> 3.10.2,3.10.6 VMs on win32; the worker process always terminates >> without >> an exception. >> >> The implementation of #waitForDataFor: >> (#waitForDataFor:ifClosed:ifTimedOut:) looks like #dataAvailable >> returns >> true but there cannot be any data since nothing was ever sent. *but* >> after >> closing the client side, the other side's #dataAvailable >> (#primSocketReceiveDataAvailable) returns true ... >> >> Any hint(s) on what's going on (or wrong) will be recognized with >> gratitude. >> >> /Klaus >> >> | localhost serverSocket sessionSocket clientSocket worker | >> >> localhost := NetNameResolver localHostAddress. >> "warning:" Socket allInstancesDo: [:socket | socket destroy]. >> serverSocket := Socket newTCP listenOn: 7680 backlogSize: 1. >> clientSocket := Socket newTCP connectNonBlockingTo: localhost port: >> 7680. >> sessionSocket := serverSocket waitForAcceptFor: 1. >> worker := [sessionSocket waitForDataFor: 1] fork. >> Processor yield. >> Transcript cr; show: serverSocket statusString, ' [server]'; >> cr; show: clientSocket statusString, ' [client]'; >> cr; show: sessionSocket statusString, ' [session], >> dataAvailable: ' >> , sessionSocket dataAvailable storeString; >> cr; show: 'worker: ', worker browserPrintString. >> [clientSocket close] on: Exception do: [:ex|]. >> Processor yield. >> Transcript cr; show: serverSocket statusString, ' [server]'; >> cr; show: clientSocket statusString, ' [client]'; >> cr; show: sessionSocket statusString, ' [session], >> dataAvailable: ' >> , sessionSocket dataAvailable storeString; >> cr; show: 'worker: ', worker browserPrintString; cr. >> [sessionSocket destroy] on: Exception do: [:ex|]. >> [clientSocket destroy] on: Exception do: [:ex|]. >> [serverSocket destroy] on: Exception do: [:ex|] >> >> >> > > |
On 25/02/2008, Klaus D. Witzel <[hidden email]> wrote:
> On Mon, 25 Feb 2008 16:24:43 +0100, Igor Stasenko wrote: > > > I think it was done intentionally, > > when socket closed , it signals that data available, to awake process > > which waiting for data. Then, when process tries to read it, it > > returns 0 bytes. > > > Nothing speaks against such behavior except the method's comment "Wait for > the given nr of seconds for data to arrive. Signal a time out or > connection close exception if either happens before data becomes > available." > > > > I think it's same as with socket's read() function. > > If remote side closed gracefully, a blocking read() function returns > > with 0, indicating that there 0 bytes read, and connection is closed. > > > So senders of #waitForDataFor: cannot know about closed connections (even > if the comment says the opposite) and *must* do at least #receiveSomeData > because #waitForDataFor: can't handle all the possible situations? > I really don't know how primitives handling this. So it's only my guess why data signaled when there is no data at all. -- Best regards, Igor Stasenko AKA sig. |
Some thoughts at
http://www.smalltalkconsulting.com/html/OTNotes1.html http://www.smalltalkconsulting.com/html/OTNotes2.html http://www.smalltalkconsulting.com/html/OTNotes3.html http://www.smalltalkconsulting.com/html/OTNotes4.html http://www.smalltalkconsulting.com/html/OTNotes5.html These might not match reality any more. On Feb 25, 2008, at 9:31 AM, Igor Stasenko wrote: > I really don't know how primitives handling this. So it's only my > guess why data signaled when there is no data at all. > > -- > Best regards, > Igor Stasenko AKA sig. > -- = = = ======================================================================== John M. McIntosh <[hidden email]> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com = = = ======================================================================== |
In reply to this post by Igor Stasenko
The situation is even more strange with one particular sender of
#waitForDataFor*, when attempting to receive data *after* the Socket had been disconnected on this side: | localhost serverSocket clientSocket worker | localhost := NetNameResolver localHostAddress. "warning" Socket allInstancesDo: [:socket | socket destroy]. serverSocket := Socket newTCP listenOn: 7680. clientSocket := Socket newTCP connectTo: localhost port: 7680. [clientSocket disconnect] on: Exception do: [:ex|]. (Delay forMilliseconds: 125) wait. worker := [clientSocket receiveDataTimeout: 1 into: (ByteArray new: 1) startingAt: 1] forkAt: Processor activeProcess priority. (Delay forMilliseconds: 125) wait. Transcript cr; show: serverSocket statusString, ' [server]'; cr; show: clientSocket statusString, ' [client], dataAvailable: ' , clientSocket dataAvailable storeString; cr; show: 'worker: ', worker browserPrintString; cr. [clientSocket destroy] on: Exception do: [:ex|]. [serverSocket destroy] on: Exception do: [:ex|] No exception: #receiveDataTimeout* passes empty blocks to #waitForDataFor* :( - http://bugs.squeak.org/view.php?id=6951 On Mon, 25 Feb 2008 18:31:51 +0100, Igor Stasenko wrote: > On 25/02/2008, Klaus D. Witzel wrote: >> On Mon, 25 Feb 2008 16:24:43 +0100, Igor Stasenko wrote: >> >> > I think it was done intentionally, >> > when socket closed , it signals that data available, to awake process >> > which waiting for data. Then, when process tries to read it, it >> > returns 0 bytes. >> >> >> Nothing speaks against such behavior except the method's comment "Wait >> for >> the given nr of seconds for data to arrive. Signal a time out or >> connection close exception if either happens before data becomes >> available." >> >> >> > I think it's same as with socket's read() function. >> > If remote side closed gracefully, a blocking read() function returns >> > with 0, indicating that there 0 bytes read, and connection is closed. >> >> >> So senders of #waitForDataFor: cannot know about closed connections >> (even >> if the comment says the opposite) and *must* do at least >> #receiveSomeData >> because #waitForDataFor: can't handle all the possible situations? >> > > I really don't know how primitives handling this. So it's only my > guess why data signaled when there is no data at all. > |
Free forum by Nabble | Edit this page |