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