> On 19 May 2015, at 10:53, Udo Schneider <udo.schnei...@homeaddress.de> wrote:
> 
> > Did you look in all your package caches ?
> I did. Must have been a victim of cleaning ... but maybe TimeMachine has 
> something ... thanks for the reminder.
> 
> > If it is just a small example, like one class, maybe it could be
> > added to the image, in which case it should indeed be a slice.
> The package was pretty simple. Basically only adding a few convenience 
> methods around Socket>>#setOption:value: . Still I think a usage example in 
> form of a class comment and test case might be appropriate. So unless 
> Multicast should be part of the base image I'll start with a separate package 
> first.

Since Socket is a fundamental part, and multicast is a key feature, I think it 
would logical to move it to the image itself, with a test case.

> CU,
> 
> udo
> 
> 
> On 19/05/15 10:38, Sven Van Caekenberghe wrote:
>> 
>>> On 19 May 2015, at 10:30, Udo Schneider <udo.schnei...@homeaddress.de> 
>>> wrote:
>>> 
>>> Hi Sven,
>>> 
>>> you got me :-)
>>> 
>>> I had this as a package sometime ago for my own purposes (mDNS). So I knew 
>>> it does work and how to do it. It's just I can't find that damned package 
>>> anymore...
>> 
>> Did you look in all your package caches ?
>> 
>>>> I do think making all this cross platform could be a bit harder, we'll see.
>>> It's not that hard. The socket API is the same on all supported platforms. 
>>> No surprises on *nix based OS. The only exception is Windows where the API 
>>> is the same but where you might run into some packet drops due to strange 
>>> personal FW products and "value-add" NDIS drivers for NICs. The situation 
>>> has gotten much better though since Windows Vista/7 are using multicast for 
>>> some of their services out of the box.
>>> 
>>> I will recreate it though. Should I simply publish a package or add this as 
>>> a slice?
>> 
>> Thanks a lot, Udo, a good multicast example would be super cool.
>> 
>> If it is just a small example, like one class, maybe it could be added to 
>> the image, in which case it should indeed be a slice.
>> 
>> If it is larger and more application/framework oriented, then maybe a 
>> standalone package is more interesting. We try to keep the image as modular 
>> as possible. This route would be a bit more work for you, but might make 
>> more sense if you also see it possibly growing in the future.
>> 
>>> Best Regards,
>>> 
>>> Udo
>>> 
>>> 
>>> On 19/05/15 10:20, Sven Van Caekenberghe wrote:
>>>> Hi Udo,
>>>> 
>>>> It would be good if some of this knowledge could be added inside the 
>>>> image, as class comment or methods comments. Even better would be an 
>>>> example combined with a unit test, like UDPSocketEchoTest and 
>>>> TCPSocketEchoTest - the unit test would then actively ensure this 
>>>> functionality is protected.
>>>> 
>>>> I do think making all this cross platform could be a bit harder, we'll see.
>>>> 
>>>> Sven
>>>> 
>>>>> On 19 May 2015, at 00:17, Udo Schneider <udo.schnei...@homeaddress.de> 
>>>>> wrote:
>>>>> 
>>>>> This should have been 'IP_ADD_MEMBERSHIP' of course:
>>>>> 
>>>>> imrMultiaddr := #[239 255 255 250].
>>>>> imrInterface := #[0 0 0 0].
>>>>> ipMreq := imrMultiaddr , imrInterface.
>>>>> socket setOption: 'IP_ADD_MEMBERSHIP' value: ipMreq.
>>>>> 
>>>>> 
>>>>> The "server" could be something like this (execute in first playground). 
>>>>> I used another IP address (#[239 255 255 251]) because #[239 255 255 250] 
>>>>> might already be part of the multicast group because of other processes 
>>>>> and this shows the "whole" process of subscribing to a multicast group:
>>>>> 
>>>>> [
>>>>> |  udpSocket |
>>>>>  udpSocket := Socket newUDP.
>>>>>  udpSocket setPort: 1900.
>>>>>  imrMultiaddr := #[239 255 255 251].
>>>>>  imrInterface := #[0 0 0 0].
>>>>>  ipMreq := imrMultiaddr , imrInterface.
>>>>>  udpSocket setOption: 'IP_ADD_MEMBERSHIP' value: ipMreq.
>>>>>  udpSocket setOption: 'IP_MULTICAST_LOOP' value: 1.
>>>>>  "udpSocket setOption: 'SO_REUSEADDR' value: 1."
>>>>>  udpSocket waitForData.
>>>>>  buffer := ByteArray new: 256.
>>>>>  data := udpSocket receiveUDPDataInto: buffer.
>>>>>  bytesRead := data at: 1.
>>>>>  sender := data at: 2.
>>>>>  senderPort := data at: 3.
>>>>>  more := data at: 4.
>>>>>  result := buffer copyFrom: 1 to: bytesRead.
>>>>>  udpSocket closeAndDestroy.
>>>>>  result asString inspect.
>>>>> ] fork.
>>>>> 
>>>>> 
>>>>> 
>>>>> The "client" (execute in different playground):
>>>>> | message udpSocket |
>>>>>  message := String crlf join: #(
>>>>>   'M-SEARCH * HTTP/1.1'
>>>>>   'HOST:239.255.255.250:1900'
>>>>>   'MAN:"ssdp:discover'
>>>>>   'ST:ssdp:all'
>>>>>   'MX:1'
>>>>>   '').
>>>>> 
>>>>>  udpSocket := Socket newUDP.
>>>>>  udpSocket sendData: message toHost: #[239 255 255 251] port: 1900.
>>>>>  (udpSocket waitForSendDoneFor: 5).
>>>>>  udpSocket closeAndDestroy.
>>>>> 
>>>>> Hope this helps.
>>>>> 
>>>>> CU,
>>>>> 
>>>>> Udo
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> On 18/05/15 23:29, Udo Schneider wrote:
>>>>>> Hi Manfred,
>>>>>> 
>>>>>> I just stumbled over the IP address you are using (239.255.255.250). If
>>>>>> I remember correctly this is a IPv4 Class D Multicast address.
>>>>>> (224.0.0.0-239.255.255.255).
>>>>>> 
>>>>>> So if you want to transmit datagrams to this IP address or recieve
>>>>>> datagrams sent to this multicast groups you have to set appropriate IP
>>>>>> Options.
>>>>>> 
>>>>>> You can set this options using Socket>>#setOption:value: and read them
>>>>>> using Socket>>#getOption:. Please note that both methods expect the
>>>>>> option to set as a name - not as constant. E.g.
>>>>>> 
>>>>>> socket setOption: 'IP_MULTICAST_IF' value: multicastInterface.
>>>>>> 
>>>>>> If I do remember correctly you have to set the following options for
>>>>>> sending/receiving:
>>>>>> 
>>>>>> Sending:
>>>>>> IP_MULTICAST_IF
>>>>>> (IP_MULTICAST_LOOP)
>>>>>> (IP_MULTICAST_TTL)
>>>>>> 
>>>>>> Sending should AFAIK work w/o setting any option - although
>>>>>> IP_MULTICAST_IF is highly recommended.
>>>>>> 
>>>>>> Receiving:
>>>>>> (SO_REUSEADDR)
>>>>>> IP_ADD_MEMBERSHIP
>>>>>> (IP_DROP_MEMBERSHIP)
>>>>>> 
>>>>>> Receiving only works if you joined the multicast group previously. So I
>>>>>> assume that you need to do something like this (not tested).
>>>>>> 
>>>>>> imrMultiaddr := #[239 255 255 250].
>>>>>> imrInterface := #[0 0 0 0].
>>>>>> ipMreq := imrMultiaddr , imrInterface.
>>>>>> socket setOption: 'MEMBERSHIP' value: ipMreq.
>>>>>> 
>>>>>> Hope this helps.
>>>>>> 
>>>>>> CU,
>>>>>> 
>>>>>> Udo
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> On 18/05/15 16:34, Manfred Kröhnert wrote:
>>>>>>> Hi Sven,
>>>>>>> 
>>>>>>> On Mon, May 18, 2015 at 4:14 PM, Sven Van Caekenberghe
>>>>>>> <s...@stfx.eu
>>>>>>> <mailto:s...@stfx.eu>> wrote:
>>>>>>> 
>>>>>>> 
>>>>>>>     > On 18 May 2015, at 15:47, Manfred Kröhnert
>>>>>>>    <mkroehner...@googlemail.com
>>>>>>>    <mailto:mkroehner...@googlemail.com>> wrote:
>>>>>>>     >
>>>>>>>     > Hi,
>>>>>>>     > apparently I am missing something else.
>>>>>>>     >
>>>>>>>     > I can find devices when connected to a 'regular' LAN.
>>>>>>>     >
>>>>>>>     > However, I have a camera that creates a Wifi accesspoint and
>>>>>>>    makes itself discoverable via SSDP.
>>>>>>>     > Once I connect to this accesspoint my computer gets a valid IP
>>>>>>>    address assigned and the NodeJS code is able to discover the device.
>>>>>>>     > Unfortunately, the Pharo snippet I posted before does not give me
>>>>>>>    any results and hangs in Socket>>waitForDataIfClosed: .
>>>>>>>     >
>>>>>>>     > Any further ideas?
>>>>>>> 
>>>>>>>    Are you sure you restarted the image and your code after switching
>>>>>>>    networks ?
>>>>>>> 
>>>>>>> 
>>>>>>> I did not check this before.
>>>>>>> But I just downloaded a fresh 40613 image with PharoLauncher and started
>>>>>>> it after connecting to the camera accesspoint.
>>>>>>> The code snippet freezes there as well.
>>>>>>> 
>>>>>>> Manfred
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>> 
>>>> 
>>>> 
>>> 
>>> 
>>> 
>> 
>> 
>> 
> 
> 
> 


Reply via email to