Javascript 发送广播数据报

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6177423/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:34:54  来源:igfitidea点击:

Send Broadcast datagram

javascriptnode.jsudpbroadcastmulticast

提问by Wassim AZIRAR

I need to send a broadcast datagram to all machine (servers) connected to my network.

我需要向连接到我的网络的所有机器(服务器)发送广播数据报。

I'm using NodeJS Multicast

我正在使用 NodeJS 多播

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.

谢谢。

采纳答案by zneak

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_BROADCASTsocket option to be able to send datagrams to the broadcast address. Looking up the dgramdocumentation, there seems to be a function for it.

我从未使用过 Node.js,但我确实记得使用 Berkely 套接字(这似乎是最广泛使用的套接字实现)需要启用SO_BROADCAST套接字选项才能将数据报发送到广播地址。查找dgram文档,似乎有一个函数

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.

您可能想以编程方式找出广播地址,但我无法帮助您。

回答by Joseph238

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 广播和多播。希望这能让其他人更容易,因为这个话题很难在网上找到答案。这些解决方案适用于 Node 版本 6.x-12.x:

UDP Broadcasting

UDP广播

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.

广播地址 = (~子网掩码) | (主机的 IP 地址) - 参见维基百科。使用ipconfig(Windows) 或ifconfig(Linux),或检查网络掩码模块

Server(remember to change BROADCAST_ADDR to the correct broadcast address)

服务器(记得把 BROADCAST_ADDR 改成正确的广播地址)

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

UDP多播

Multicast addresses

组播地址

Looking at the IPv4 Multicast Address Space Registryand more in-depth clarification in the RFC 2365 manualsection 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).

查看IPv4 多播地址空间注册表RFC 2365 手册第 6 节中更深入的说明,我们发现适当的本地范围多播地址是 239.255.0.0/16 和 239.192.0.0/14(也就是说,除非您获得许可使用其他的)。

The multicast code below works just fine on Linux (and many other platforms) with these addresses.

下面的多播代码在具有这些地址的 Linux(和许多其他平台)上工作得很好。

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:

大多数操作系统通过特定接口发送和侦听多播,默认情况下,如果有多个接口可用,它们通常会选择错误的接口,因此您永远不会在另一台机器上接收多播(您只能在本地主机上接收它们)。在Node.js 文档中阅读更多内容。要使代码可靠地工作,请更改代码,以便为要使用的接口指定主机的 IP 地址,如下所示:

Server - server.bind(SRC_PORT, HOST_IP_ADDRESS, function() ...

服务器 - server.bind(SRC_PORT, HOST_IP_ADDRESS, function() ...

Client - client.addMembership(MULTICAST_ADDR, HOST_IP_ADDRESS);

客户 - client.addMembership(MULTICAST_ADDR, HOST_IP_ADDRESS);

Take a look at these supporting sources: NodeJS, Java, C#, and a helpful commandto see which multicast addresses you are subscribed to - netsh interface ipv4 show joins.

看看这些支持来源:NodeJSJavaC#和一个有用的命令来查看您订阅了哪些多播地址 - 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 optionsfor server.send(named socket.sendin the docs). You can use a string for the msginstead 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.

更新:其他选项server.send(命名socket.send的文档)。您可以使用字符串msg代替 Buffer,并且根据您的版本,有几个参数是可选的。您还可以检查回调函数中是否发生了错误。

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.

更新:自 Node.js v6 起,new Buffer(str)不推荐使用Buffer.from(str). 上面的代码已更新以反映此更改。如果您使用的是较早版本的 Node,请使用以前的语法。

回答by Ingemar

I think since node 0.10.0 some things has changed this works for me now:

我认为自节点 0.10.0 以来,有些事情已经改变了这对我现在有效:

//var broadcastAddress = "127.255.255.255";
var broadcastAddress = "192.168.0.255";

var message = new Buffer("Some bytes");

var client = dgram.createSocket("udp4");
client.bind();
client.on("listening", function () {
    client.setBroadcast(true);
    client.send(message, 0, message.length, 6623, broadcastAddress, function(err, bytes) {
        client.close();
    });
});

Hope this helps somebody ;)

希望这有助于某人;)