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