Am 27.03.2013 um 00:25 schrieb Sven Van Caekenberghe <[email protected]>:

> 
> On 26 Mar 2013, at 23:46, Norbert Hartl <[email protected]> wrote:
> 
>> Am 26.03.2013 um 21:08 schrieb Sven Van Caekenberghe <[email protected]>:
>> 
>>> Hi Holger,
>>> 
>>> On 26 Mar 2013, at 12:12, Holger Hans Peter Freyther <[email protected]> 
>>> wrote:
>>> 
>>>> Hi,
>>>> 
>>>> I am porting a tooling class that I wrote on GST for my SIP and MGCP code
>>>> to Pharo. This class will create a socket and then fork a RX and TX 
>>>> process.
>>>> I have some issues with 'stopping' the socket. I have created an example
>>>> that shows the issue in Pharo 2.0 and Pharo 1.4 with the pharovm (and to
>>>> have more debug output with a re-compiled one).
>>>> 
>>>> 
>>>>    | s rx |
>>>>    s := Socket newUDP.
>>>>    rx := [
>>>>            [s waitForData. s halt]
>>>>                    on: ConnectionClosed do: [ s halt]
>>>>            ] fork.
>>>>    "Wait for the process to hit the readSemaphore"
>>>>    (Delay forSeconds: 3) wait.
>>>>    s close.
>>>> 
>>>> 
>>>> My expectation is that I will get the ConnectionClosed signal or at least
>>>> that >>#waitForData will return once the socket is closed. This is based
>>>> on reading the comment of >>#waitForData.
>>>> 
>>>> 
>>>> The Socket>>#waitForData documentation reads like this:
>>>>    "Wait for data to arrive.  This method will block until
>>>>    data is available or the socket is closed.  If the socket is closed
>>>>    a ConnectionClosed exception will be signaled."
>>>> 
>>>> 
>>>> I had a look at the socket plugin and the following is happening. First
>>>> aio is disabled, the state set to ThisEndClosed, then ::close is called
>>>> and in the above case the result is '0' and the following code will be
>>>> executed:
>>>> 
>>>> else if (0 == result)
>>>>  {
>>>>    /* close completed synchronously */
>>>>    SOCKETSTATE(s)= Unconnected;
>>>>    FPRINTF((stderr, "closeConnection: disconnected\n"));
>>>>    SOCKET(s)= -1;
>>>>  }
>>>> 
>>>> 
>>>> this means that my 'rx' process will happily wait on the readSemaphore
>>>> of the Socket and will never be woken up.
>>>> 
>>>> 
>>>> My question are probably:
>>>> 
>>>> 1.) Is this the intended behavior for Socket>>#close and 
>>>> Socket>>#waitForData?
>>>> 2.) How should I terminate my RX process?
>>>> 
>>>> kind regards
>>>>    holger
>>>> 
>>>> PS: The issue is probably socket specific and not related to UDP.
>>> 
>>> Maybe I am telling you things you already know, but TCP and UDP are 
>>> fundamentally different. UDP is really one-shot, try-and-hope, completely 
>>> asynchronous. In networking you generally only get a ConnectionClosed when 
>>> you actually read or write (and even then ;-). 
>>> 
>> That's not really true. It is implementation specific. IMHO you can open a 
>> UDP socket in send and receive mode where the communication is synchronous. 
>> So your socket blocks until a datagram socket is received. This has to 
>> advantage that the underlying OS registers local and remote port and 
>> automatically and accepts only datagrams for the right ports match. As it is 
>> in a lot of use cases not preferrable to have blocking sockets while using 
>> UDP you use two sockets instead, one for sending and one for receiving. For 
>> this you need to register the listening socket for listening to everything. 
>> Disclaimer: I took this from the back of my head and this might by 
>> outdated/inproper information. I just wanted to say that you shouldn't mix 
>> asynchronous with unidirectional :) 
>> 
>> Norbert
> 
> I politely disagree ;-)
> 
> But I am willing to learn: so please provide some references of such UDP 
> usage.
> 
> http://en.wikipedia.org/wiki/Datagram
> 
If I find the time I dig out some things from the past. I just can't follow 
your reasoning that the way UDP is defined means unidirectional. TCP defines a 
connection, UDP does not. Connections are not required to have end-to-end 
communication. A remote port is a service identifier and local port is a client 
identifier. A port pair defines a communication channel. TCP just adds roles to 
both ends and defines stream sequences and transmission windows. 
Maybe I misunderstood you then I take everything back :)

Norbert

>>> The Socket API has many strange methods, most of which you should not 
>>> touch. You should use SocketStream. Looking in the VM code is also 
>>> misleading because the 3 platforms (Mac, Win, *nix) are different. In 
>>> Socket[Stream] there is lots of historic baggage.
>>> 
>>> I would suggest you look at Smalltalk code that actually works (for TCP, 
>>> Zinc Client and Server code would do, for UDP, ZTimestampSNTPClient for 
>>> example).
>>> 
>>> For your concrete question (2): just start a reading process, wrap it in a 
>>> handler and clean up. For UDP this will never happen: you will keep on 
>>> reading nothing. For TCP reading will eventually fail if the other end 
>>> disappears.
>>> 
>>> HTH,
>>> 
>>> Sven 
>>> 
>>> --
>>> Sven Van Caekenberghe
>>> http://stfx.eu
>>> Smalltalk is the Red Pill
>>> 
>>> 
>> 
>> 
> 
> 


Reply via email to