I need to send a broadcast datagram to all machine (servers) connected to my network.
I'm using NodeJS Multicast
Client
var dgram = require('dgram');
var message = new Buffer("Some bytes");
var client = dgram.createSocket("udp4");
client.send(message, 0, message.length, 41234, "localhost");
// If I'm in the same machine 'localhost' works
// I need to do something 192.168.0.255 or 255.255.255
client.close();
Servers
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) {
console.log("server got: " + msg + " from " +
rinfo.address + ":" + rinfo.port);
});
server.on("listening", function () {
var address = server.address();
console.log("server listening " + address.address + ":" + address.port);
});
server.bind(41234);
Thanks.
I spent a lot of time trying to be able to do UDP broadcasting and multicasting between computers. Hopefully this makes it easier for others since this topic is quite difficult to find answers for on the web. These solutions work in Node versions 6.x-12.x:
UDP Broadcasting
Calculate the broadcast address
Broadcast address = (~subnet mask) | (host's IP address) - see Wikipedia. Use ipconfig
(Windows) or ifconfig
(Linux), or checkout the netmask module.
Server (remember to change BROADCAST_ADDR to the correct broadcast address)
var PORT = 6024;
var BROADCAST_ADDR = "58.65.67.255";
var dgram = require('dgram');
var server = dgram.createSocket("udp4");
server.bind(function() {
server.setBroadcast(true);
setInterval(broadcastNew, 3000);
});
function broadcastNew() {
var message = Buffer.from("Broadcast message!");
server.send(message, 0, message.length, PORT, BROADCAST_ADDR, function() {
console.log("Sent '" + message + "'");
});
}
Client
var PORT = 6024;
var dgram = require('dgram');
var client = dgram.createSocket('udp4');
client.on('listening', function () {
var address = client.address();
console.log('UDP Client listening on ' + address.address + ":" + address.port);
client.setBroadcast(true);
});
client.on('message', function (message, rinfo) {
console.log('Message from: ' + rinfo.address + ':' + rinfo.port +' - ' + message);
});
client.bind(PORT);
UDP Multicasting
Multicast addresses
Looking at the IPv4 Multicast Address Space Registry and more in-depth clarification in the RFC 2365 manual section 6, we find the appropriate local scope multicast addresses are 239.255.0.0/16 and 239.192.0.0/14 (that is, unless you obtain permission to use other ones).
The multicast code below works just fine on Linux (and many other platforms) with these addresses.
Most operating systems send and listen for multicasts via specific interfaces, and by default they will often choose the wrong interface if multiple interfaces are available, so you never receive multicasts on another machine (you only receive them on localhost). Read more in the Node.js docs. For the code to work reliably, change the code so you specify the host's IP address for the interface you wish to use, as follows:
Server - server.bind(SRC_PORT, HOST_IP_ADDRESS, function() ...
Client - client.addMembership(MULTICAST_ADDR, HOST_IP_ADDRESS);
Take a look at these supporting sources: NodeJS, Java, C#, and a helpful command to see which multicast addresses you are subscribed to - netsh interface ipv4 show joins
.
Server
var SRC_PORT = 6025;
var PORT = 6024;
var MULTICAST_ADDR = '239.255.255.250';
var dgram = require('dgram');
var server = dgram.createSocket("udp4");
server.bind(SRC_PORT, function () { // Add the HOST_IP_ADDRESS for reliability
setInterval(multicastNew, 4000);
});
function multicastNew() {
var message = Buffer.from("Multicast message!");
server.send(message, 0, message.length, PORT, MULTICAST_ADDR, function () {
console.log("Sent '" + message + "'");
});
}
Client
var PORT = 6024;
var MULTICAST_ADDR = '239.255.255.250';
var dgram = require('dgram');
var client = dgram.createSocket('udp4');
client.on('listening', function () {
var address = client.address();
console.log('UDP Client listening on ' + address.address + ":" + address.port);
});
client.on('message', function (message, rinfo) {
console.log('Message from: ' + rinfo.address + ':' + rinfo.port + ' - ' + message);
});
client.bind(PORT, function () {
client.addMembership(MULTICAST_ADDR); // Add the HOST_IP_ADDRESS for reliability
});
UPDATE: There are additional options for server.send
(named socket.send
in the docs). You can use a string for the msg
instead of a Buffer, and depending on your version, several parameters are optional. You can also check whether an error has occurred in the callback function.
UPDATE: Since Node.js v6, new Buffer(str)
is deprecated in favor of Buffer.from(str)
. The code above has been updated to reflect this change. If you are using an earlier version of Node, use the former syntax.
I never used Node.js, but I do recall that with Berkely sockets (which seem to be the most widely used implementation of sockets) you need to enable the SO_BROADCAST
socket option to be able to send datagrams to the broadcast address. Looking up the dgram
documentation, there seems to be a function for it.
var client = dgram.createSocket("udp4");
client.setBroadcast(true);
client.send(message, 0, message.length, 41234, "192.168.0.255");
You might want to find out the broadcast address programmatically, but I can't help you with that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With