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