When binding a dgram udp socket on a specific address my program does not receive any multicast message.
Here are 3 programs that demonstrate the problem:
receive-all-addresses.js
var dgram = require('dgram');
var s = dgram.createSocket('udp4');
var MULTICAST_IP = "225.0.0.1"
s.bind(8001, function() {
s.addMembership(MULTICAST_IP);
console.log("listening on all addresses");
});
s.on("message", function (msg, rinfo) {
console.log("server got: " + msg + " from " +
rinfo.address + ":" + rinfo.port);
});
receive-specific-address.js
var dgram = require('dgram');
var s = dgram.createSocket('udp4');
var MULTICAST_IP = "225.0.0.1"
var LOCAL_IP = "10.80.10.23"
s.bind(8001, LOCAL_IP, function() {
s.addMembership(MULTICAST_IP);
console.log("listening on a specific address");
});
s.on("message", function (msg, rinfo) {
console.log("server got: " + msg + " from " +
rinfo.address + ":" + rinfo.port);
});
send.js
var dgram = require('dgram');
var s = dgram.createSocket('udp4');
var MULTICAST_IP = "225.0.0.1"
var LOCAL_IP = "10.80.10.23"
s.bind(8000);
function sendDirectHello(s)
{
var b = new Buffer("Direct Hello!");
s.send(b, 0, b.length, 8001, LOCAL_IP, function(err, bytes) {
console.log("Sent " + bytes + " bytes");
s.close();
});
}
function sendMulticastThenDirectHello(s)
{
var b = new Buffer("Multicast Hello!");
s.send(b, 0, b.length, 8001, MULTICAST_IP, function(err, bytes) {
console.log("Sent " + bytes + " bytes");
sendDirectHello(s);
});
}
sendMulticastThenDirectHello(s);
When listening on all addresses the program receives both messages from send.js:
pi@raspberrypi-js ~/udp_multicast $ iojs receive-all-addresses.js
listening on all addresses
server got: Multicast Hello! from 10.80.10.23:8000
server got: Direct Hello! from 10.80.10.23:8000
but when listening on a single address the program only receives the direct message:
pi@raspberrypi-js ~/udp_multicast $ iojs receive-specific-address.js
listening on a specific address
server got: Direct Hello! from 10.80.10.23:8000
The problem has been reproduced with io.js 1.6.4 and 2.0.1 (linux armv6l, linux x64).
Have you tried the multicast address 224.0.0.114 ??
I tried your scripts on the address, it works fine.
And according to our api docs, example code uses 224.0.0.114.
https://iojs.org/api/dgram.html
I tried with 224.0.0.114 but have the same issue.
I checked the packets with Wireshark and can confirm that the membership is properly added and the multicast message is sent.
I get the same behavior as @tberthe whether I use 224.0.0.114 or 225.0.0.1 (after updating LOCAL_IP to be my IP), and I get that behavior whether I use Node.js 1.6.4 or Node.js 5.7.1.
I have exactly the same issue but only on Linux (Debian 8.4), use bind with a specific address is working fine on Windows (10). Linux sends packets with specific address but cannot receive. With Linux or Windows, i have multiple interfaces (ethernet, wifi, Docker...). I'm using Node 6.1.0. Tested with many multicast addresses without success. Disabling the unused interfaces has no effect.
I've been looking into this and _think_ it works as expected. IIUIC, to receive a multicast datagram you have 2 options:
receive-all-addresses.js. This way, you can receive every message sent to that port whether multicast or not.receive-specific-address.js but binding to MULTICAST_IP instead of LOCAL_IP.On the other hand, if you want to restrict from which interface the multicast messages are received you can use the multicastInterface argument in addMembership. For example: s.addMembership(MULTICAST_IP, LOCAL_IP); will allow to receive multicast messages received in the LOCAL_IP interface.
Thanks @santigimeno, works for me :-)
Closing this. If anyone feels it should be re-open, please do.
Most helpful comment
I've been looking into this and _think_ it works as expected. IIUIC, to receive a multicast datagram you have 2 options:
receive-all-addresses.js. This way, you can receive every message sent to that port whether multicast or not.receive-specific-address.jsbut binding toMULTICAST_IPinstead ofLOCAL_IP.On the other hand, if you want to restrict from which interface the multicast messages are received you can use the
multicastInterfaceargument inaddMembership. For example:s.addMembership(MULTICAST_IP, LOCAL_IP);will allow to receive multicast messages received in theLOCAL_IPinterface.