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