yes examples are good.
but I also suggest to use a stream on a UDPSocket instead of manipulating
the socket directly in the model code.
Usually, it lowers the code complexity.

Luc

2014-10-21 10:36 GMT+02:00 Sven Van Caekenberghe <s...@stfx.eu>:

> OK good.
>
> I think it would be best to add some examples to the image:
>
>
> https://pharo.fogbugz.com/f/cases/14275/Add-some-decent-TCP-UDP-examples-and-tests
>
> I will do that in the coming days.


> > On 21 Oct 2014, at 10:20, Annick Fron <l...@afceurope.com> wrote:
> >
> > OK super, this example works. I got confused because I did not
> understand that you had 2 variables, buffer passed as argument and result
> as return.
> >
> > Annick
> > Le 21 oct. 2014 à 09:53, Sven Van Caekenberghe <s...@stfx.eu> a écrit :
> >
> >> The buffer that you supply to #receiveUDPDataInto: is either a String
> or a ByteArray, preallocated to a certain size. It gets filled with the
> incoming data part of the datagram. It should be large enough, it never
> overflows, if it is too small, you simply miss data (it is lost). If you
> preallocate N bytes, the result, the incoming data, might be less.
> >>
> >> The result from #receiveUDPDataInto: is a 4 element array, that I
> described before. The fields you are looking for are in the second (the ip
> address of the sender, a 4 element byte array) and in third (the port of
> the sender) slot. The first element is the actual number of bytes read. You
> need to copy from 1 to that size out of the buffer.
> >>
> >> The other fields that are in a datagram, outside the user data, are not
> accessible. You don't need them, unless you are implementing a TCP/IP stack
> yourself.
> >>
> >> Did you try this example ?
> >>
> >> "An UDP echo server on port 6666"
> >> [ Socket newUDP in: [ :socket |
> >> | loop buffer result input |
> >> buffer := String new: 256.
> >> loop := true.
> >> socket setPort: 6666.
> >> [ loop ] whileTrue: [
> >>  [ result := socket receiveUDPDataInto: buffer.
> >>    result first > 0 ] whileFalse: [ (Delay forMilliseconds: 10) wait ].
> >>  input := buffer copyFrom: 1 to: result first.
> >>  socket sendUDPData: input toHost: result second port: result third.
> >>  (input beginsWith: #quit) ifTrue: [ loop := false ] ].
> >>  socket closeAndDestroy ] ] forkAt: Processor userBackgroundPriority
> named: 'UDP echo server'.
> >>
> >> "Any message sent gets echoed back"
> >> Socket newUDP in: [ :socket |
> >> | buffer result |
> >> socket sendUDPData: 'testing ', 99 atRandom asString toHost:
> NetNameResolver localHostAddress port: 6666.
> >> buffer := String new: 256.
> >> [ result := socket receiveUDPDataInto: buffer.
> >>  result first > 0 ] whileFalse: [ (Delay forMilliseconds: 10) wait ].
> >> socket closeAndDestroy.
> >> { result. buffer. buffer copyFrom: 1 to: result first } ].
> >>
> >> "Send quit to stop the server"
> >> Socket newUDP in: [ :socket |
> >> | buffer result |
> >> socket sendUDPData: 'quit' toHost: NetNameResolver localHostAddress
> port: 6666.
> >> buffer := String new: 256.
> >> [ result := socket receiveUDPDataInto: buffer.
> >>  result first > 0 ] whileFalse: [ (Delay forMilliseconds: 10) wait ].
> >> socket closeAndDestroy.
> >> { result. buffer. buffer copyFrom: 1 to: result first } ].
> >>
> >> In a terminal (OSX or Linux), you can send a message like this:
> >>
> >> $ nc -u 127.0.0.1 6666
> >> foo bar
> >> foo bar
> >> quit
> >> quit
> >>
> >>> On 21 Oct 2014, at 09:31, Annick Fron <l...@afceurope.com> wrote:
> >>>
> >>> Sven,
> >>>
> >>> I have put a halt in your sync method, but receiveUDPData comes with
> 64 bytes in your app, whereas you have provisioned 48 bytes.
> >>> So since you start data at 33, I guess what you receive is the usual
> datagram IP header on 16 bytes, then the UDP header on 16 bytes.
> >>>
> http://fr.wikipedia.org/wiki/Internet_Protocol#mediaviewer/File:Ipv4_header.svg
> >>> http://fr.wikipedia.org/wiki/User_Datagram_Protocol
> >>>
> >>> If this is correct, I should see the source IP address on 4 bytes
> starting at byte 9, and the total length should be on 4 bytes starting at
> byte 5, and not at byte 1.
> >>>
> >>> Annick
> >>>
> >>> Le 20 oct. 2014 à 17:29, Sven Van Caekenberghe <s...@stfx.eu> a écrit
> :
> >>>
> >>>> Annick,
> >>>>
> >>>>> On 20 Oct 2014, at 17:12, Annick Fron <l...@afceurope.com> wrote:
> >>>>>
> >>>>> Thank you but your explanation does not explain what is the type
> (signed unsigned) and the size of each header component.
> >>>>> Thus it is impossible to work with that.
> >>>>
> >>>> I think you are making this way more difficult than it is.
> >>>>
> >>>> ZTimestampSNTPClient>>#sync contains a simple, runnable example of
> using datagrams (with a busy wait blocking the calling thread, which is
> only good for something simple, because normally datagrams are
> asynchronous, but that is another story).
> >>>>
> >>>> What you get back from #receiveUDPDataInto: is an Array with 4
> elements:
> >>>>
> >>>> - number of bytes received, Integer
> >>>> - address of sender, ByteArray (use NetNameResolver if necessary)
> >>>> - port of sender, Integer
> >>>> - whether more datagrams are available for reading, Boolean
> >>>>
> >>>> The data is in the reallocated buffer that you supplied,
> aStringOrByteArray.
> >>>>
> >>>> This is all perfectly useable at the Pharo level.
> >>>>
> >>>> The question about signed/unsigned sounds like a C question, for
> which this is the wrong list, no ? I am sure it is quite easy to find C
> code that works with datagrams on your platform. A byte array is an
> unsigned char array as far as I remember ...
> >>>>
> >>>> What you put inside the datagram, is up to you and your application.
> >>>>
> >>>> HTH,
> >>>>
> >>>> Sven
> >>>>
> >>>>> Annick
> >>>>>
> >>>>> Le 17 oct. 2014 à 19:09, Sven Van Caekenberghe <s...@stfx.eu> a
> écrit :
> >>>>>
> >>>>>> Yes, you have to use the methods in the protocol 'datagrams' of
> Socket.
> >>>>>>
> >>>>>> When you receive a datagram, the IP:PORT of the other party is
> included, see #receiveUDPDataInto:'c comment.
> >>>>>>
> >>>>>> It is all a bit low level, but it works well.
> >>>>>>
> >>>>>> On 17 Oct 2014, at 18:15, Annick Fron <l...@afceurope.com> wrote:
> >>>>>>
> >>>>>>> Thank you, but I am confused.
> >>>>>>> I have checked your NTP code, and it uses
> >>>>>>> sendUDPData and not sendData. Same for receiveUDPData.
> >>>>>>> Besides how is it possible to know where the message comes from in
> a broadcast mode ??
> >>>>>>> Annick
> >>>>>>> Le 17 oct. 2014 à 17:35, Sven Van Caekenberghe <s...@stfx.eu> a
> écrit :
> >>>>>>>
> >>>>>>>> UDP is pretty easy, just send and receive byte arrays basically,
> mostly non-blocking.
> >>>>>>>>
> >>>>>>>> http://forum.world.st/UDP-Listener-example-td4362851.html
> >>>>>>>> http://forum.world.st/SysLogSender-UDP-td4745862.html
> >>>>>>>>
> >>>>>>>> The API is all in Socket.
> >>>>>>>>
> >>>>>>>> On 17 Oct 2014, at 17:09, Annick Fron <l...@afceurope.com> wrote:
> >>>>>>>>
> >>>>>>>>> Hi,
> >>>>>>>>>
> >>>>>>>>> I was not able to find a UDP example in pharo.
> >>>>>>>>>
> >>>>>>>>> There are only TCP examples.
> >>>>>>>>>
> >>>>>>>>> Any pointer ?
> >>>>>>>>>
> >>>>>>>>> Annick
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>>
> >>
> >
>
>
>

Reply via email to