True - having Wireshark is always a good idea. Just a warning in the multicast context though: The fact that Wireshark sees multicast datagrams (when recieving) does only imply that your NIC is in promiscuous mode or that /a/ process on the node did subscribe to the multicast group. It does not necessarily mean that /your/ process will get the datagram via it's socket. Debugging multicast is a little bit tricky. With unicast or broadcast datagrams (doesn't matter if Ethernet or IP) it's quite easy: The NIC accepts every Broadcast L2 datagram and forwards it to the IP stack which processes every L3 broadcast datagram. For unicast the NIC only accepts datagrams sent to it's MAC address and the IP stack only processes them when sent to (one if) it's IP addresses. With multicast being "something in between" you have to convince the NIC (IP Multicast addresses map to specific Ethernet MACs) and the IP Stack to process the datagram although it's neither directly sent to their MAC/IP nor a broadcast. CU, Udo On 19/05/15 04:17, Ben Coman wrote:
Ultimate fallback, use Wireshark to compare packets on the wire between using node.js and Pharo. http://en.wikiversity.org/wiki/Wireshark/IPv4_multicast cheers -ben
On Tue, May 19, 2015 at 6:17 AM, Udo Schneider <udo.schneider@homeaddress.de <mailto:udo.schneider@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 <http://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 <sven@stfx.eu <mailto:sven@stfx.eu> <mailto:sven@stfx.eu <mailto:sven@stfx.eu>>> wrote:
> On 18 May 2015, at 15:47, Manfred Kröhnert <mkroehnert42@googlemail.com <mailto:mkroehnert42@googlemail.com>
<mailto:mkroehnert42@googlemail.com <mailto:mkroehnert42@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