2011-05-30 12 views
14

Necesito enviar un datagrama de difusión a todas las máquinas (servidores) conectadas a mi red.Send Broadcast datagram

estoy usando NodeJS multidifusión

cliente

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

Servidores

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

, gracias.

+4

¿Cuál es tu pregunta? – TJHeuvel

Respuesta

11

Nunca utilicé Node.js, pero sí recuerdo que con los conectores Berkely (que parecen ser la implementación de sockets más utilizada) debe habilitar la opción de socket SO_BROADCAST para poder enviar datagramas a la dirección de difusión . En busca de la documentación dgram, parece haber a function for it.

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

Es posible que desee conocer la dirección de transmisión mediante programación, pero no puedo ayudarle con eso.

+0

gracias señor. era el setBroadcast (verdadero); –

+3

Si usa 255.255.255.255, actuará como la dirección de difusión local según RFC922. =) – reconbot

+0

raro. incluso con este cambio, el servidor nunca parece recibir nada del cliente. – Michael

9

Creo que desde el nodo 0.10.0 algunas cosas han cambiado esto funciona para mí ahora:

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

Espero que esto ayude a alguien;)

14

pasé mucho tiempo tratando de ser capaz de hacer Transmisión UDP y multidifusión entre computadoras. Esperemos que esto lo haga más fácil para otros, ya que este tema es bastante difícil de encontrar respuestas en la web. Estas soluciones funcionan en el Nodo 0.12.5:

UDP Radiodifusión

Calcular la dirección de difusión

Dirección de difusión = (~ máscara de subred) | (dirección IP del host) - ver Wikipedia. Use ipconfig (Windows) o ifconfig (Linux), o revise el netmask module.

servidor (recuerde que debe cambiar BROADCAST_ADDR a la dirección de difusión correcta)

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 + "'"); 
    }); 
} 

cliente

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 multidifusión

direcciones de multidifusión

Mirando el IPv4 Multicast Address Space Registry y más aclaraciones en profundidad en la sección 6 RFC 2365 manual, nos encontramos con las direcciones de multidifusión ámbito local son apropiados 239.255.0.0/16 y 239.192.0.0/14 (es decir, a menos que obtenga permiso para use otros).

El código de multidifusión a continuación funciona bien en Linux (y en muchas otras plataformas) con estas direcciones.

Windows 8 (y aparentemente Windows 7 y posiblemente otros) envía y escucha multidifusiones a través de interfaces específicas, y de forma predeterminada a menudo elige la interfaz incorrecta, por lo que nunca recibirá multidifusiones en otra máquina (solo las recibe en localhost) (Me tomó horas para resolver esto a través de pruebas.) Para que el código funciona correctamente, cambie el código de modo que especifique la dirección IP del host para la interfaz que desea utilizar, de la siguiente manera:

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

Cliente - client.addMembership(MULTICAST_ADDR, HOST_IP_ADDRESS);

Tome un vistazo a estas fuentes de apoyo: NodeJS, Java, C#, y una útil command a ver qué direcciones de multidifusión que está suscrito - netsh interface ipv4 show joins

Servidor

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 + "'"); 
    }); 
} 

cliente

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); 
}); 
+0

Tengo una pregunta con respecto a la multidifusión de UDP. Tu ejemplo funciona bien teniendo solo 1 cliente. Pero, ¿qué deberíamos cambiar para tener más clientes que recibirán el mensaje multidifundido desde el servidor? ¡Gracias! – Chris

+0

Perdón por la respuesta tardía. Para que múltiples clientes reciban el mensaje multidifundido, no necesita hacer nada adicional. Cada cliente simplemente se suscribe a la misma dirección de multidifusión (usando la función 'addMembership') a la que el servidor envía el mensaje. Todos los clientes reciben el mensaje (con una tasa de éxito del 99.9% según mi experiencia, ya que UDP no es completamente confiable). – Joseph238

+0

Gracias por su respuesta. Pero en mi pregunta quise decir algo diferente. Mi objetivo es ejecutar múltiples clientes en la misma máquina (Mac OS) que todos ellos son miembros de MULTICAST_ADDR. Eso significa que todos los clientes deben tener el mismo puerto para que funcione la multidifusión. Usando su código para UDP Multicasting, necesito de alguna manera reutilizar Puerto para poder ejecutar varias veces client.js. Logré encontrar en la documentación de dgram.createSocket (options [, callback]) una opción reuseAddr field pero no pude encontrar nada sobre PORT. Le agradecería si puede proporcionar un ejemplo. – Chris