2011-05-30 131 views
14

我需要發送廣播數據報給連接到我的網絡的所有機器(服務器)。發送廣播數據報

我使用組播的NodeJS

客戶

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(); 

服務器

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); 

感謝。

+4

請告訴我你的問題? – TJHeuvel 2011-05-30 14:18:28

回答

11

我從來沒有使用Node.js,但我記得使用Berkely套接字(它似乎是套接字中使用最廣泛的實現),您需要啓用SO_BROADCAST套接字選項才能將數據報發送到廣播地址。查看dgram文檔,似乎有a function for it

var client = dgram.createSocket("udp4"); 
client.setBroadcast(true); 
client.send(message, 0, message.length, 41234, "192.168.0.255"); 

你可能想通過編程的方式找到廣播地址,但我不能幫你。

+0

謝謝先生。它是setBroadcast(true); – 2011-05-30 14:55:52

+3

如果您使用255.255.255.255,它將作爲每個RFC922的本地廣播地址。 =) – reconbot 2013-12-16 17:27:27

+0

很奇怪。即使發生這種變化,服務器也從來沒有收到客戶端的任何信息。 – Michael 2017-01-29 02:26:43

9

我想既然節點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(); 
    }); 
}); 

希望這有助於別人;)

14

我花了很多時間試圖能夠做到UDP廣播和計算機之間的多播。希望這可以讓其他人更容易,因爲這個主題很難在網上找到答案。這些解決方案在節點0.12.5工作:

UDP廣播

計算廣播地址

廣播地址=(〜子網掩碼)| (主機的IP地址) - 請參閱Wikipedia。使用ipconfig(Windows)或ifconfig(Linux),或者檢出netmask module

服務器(記得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 = new Buffer("Broadcast message!"); 
    server.send(message, 0, message.length, PORT, BROADCAST_ADDR, function() { 
     console.log("Sent '" + message + "'"); 
    }); 
} 

客戶

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多播

組播地址

縱觀IPv4 Multicast Address Space Registry和更深入的澄清在RFC 2365 manual第6節,我們找到了合適的本地範圍多播地址是239.255.0.0/16和239.192.0.0/14(也就是說,除非你獲得許可使用其他的)。

下面的組播代碼在使用這些地址的Linux(以及許多其他平臺)上工作得很好。 (通過特定的接口發送和偵聽多播),默認情況下它會經常選擇錯誤的接口,所以你永遠不會在另一臺機器上接收多播(你只能在本地主機上接收它們)。 (我花了時間通過測試圖了這一點。)對於代碼可靠地工作,更改代碼,使您指定的主機的IP地址,您希望使用的界面,如下所示:

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

客戶端 - client.addMembership(MULTICAST_ADDR, HOST_IP_ADDRESS);

看看這些支持來源:NodeJSJavaC#和樂於助人command看到你訂閱了哪些組播地址 - netsh interface ipv4 show joins

服務器

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() { 
    setInterval(multicastNew, 4000); 
}); 

function multicastNew() { 
    var message = new Buffer("Multicast message!"); 
    server.send(message, 0, message.length, PORT, MULTICAST_ADDR, function() { 
     console.log("Sent '" + message + "'"); 
    }); 
} 

客戶

​​
+0

我有一個關於UDP多播的問題。你的例子很好,只有一個客戶端。但是爲了讓更多的客戶端能夠從服務器接收到多播消息,我們應該改變什麼?謝謝! – Chris 2015-10-30 17:29:45

+0

對不起,延遲迴復。對於多個客戶端接收多播消息,您不需要額外做任何事情。每個客戶端只需訂閱服務器發送消息的相同多播地址(使用'addMembership'函數)。所有的客戶端都收到這個消息(根據我的經驗,成功率大約爲99.9%,因爲UDP並不完全可靠)。 – Joseph238 2015-11-10 19:46:32

+0

謝謝你的回答。但在我的問題中,我的意思與衆不同。我的目標是在同一臺計算機(Mac OS)上運行多個客戶端,以便它們都是MULTICAST_ADDR的成員。這意味着所有客戶端必須具有相同的PORT才能使組播工作。使用您的代碼進行UDP多播我需要以某種方式重新使用端口,以便能夠多次運行client.js。我設法在dgram.createSocket(options [,callback])的文檔中找到一個選項reuseAddr字段,但找不到有關PORT的任何信息。我會很感激你,如果你能提供這樣的例子 – Chris 2015-11-10 21:22:37