Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send Broadcast datagram

Tags:

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.

like image 789
Wassim AZIRAR Avatar asked May 30 '11 14:05

Wassim AZIRAR


Video Answer


2 Answers

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.

like image 172
Joseph238 Avatar answered Dec 13 '22 23:12

Joseph238


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.

like image 42
zneak Avatar answered Dec 13 '22 23:12

zneak