> On 21 Oct 2014, at 15:29, Luc Fabresse <luc.fabre...@gmail.com> wrote:
> 
> 
> 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.

Hmm, are you sure that is even possible with UDP sockets ? 

I have never seen that ...

> 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