NodeJS UDP Multicast Как сделать

Я пытаюсь отправить пакет UDP Multicast на: 230.185.192.108, чтобы все подписанные получат. Немного застрял. Я считаю, что он транслируется правильно, но, похоже, не могу ничего уловить ни с одним клиентом.

Сервер:

var news = [
   "Borussia Dortmund wins German championship",
   "Tornado warning for the Bay Area",
   "More rain for the weekend",
   "Android tablets take over the world",
   "iPad2 sold out",
   "Nation's rappers down to last two samples"
];

var dgram = require('dgram'); 
var server = dgram.createSocket("udp4"); 
server.bind();
server.setBroadcast(true)
server.setMulticastTTL(128);
server.addMembership('230.185.192.108'); 

setInterval(broadcastNew, 3000);

function broadcastNew() {
    var message = new Buffer(news[Math.floor(Math.random()*news.length)]);
    server.send(message, 0, message.length, 8088, "230.185.192.108");
    console.log("Sent " + message + " to the wire...");
    //server.close();
}

Клиент

var PORT = 8088;
var HOST = '192.168.0.102';
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.setMulticastTTL(128); 
    client.addMembership('230.185.192.108');
});

client.on('message', function (message, remote) {   
    console.log('A: Epic Command Received. Preparing Relay.');
    console.log('B: From: ' + remote.address + ':' + remote.port +' - ' + message);
});

client.bind(PORT, HOST);

Ссылки Подробнее о дейтаграмме NodeJS


person Taurian    schedule 02.01.2013    source источник
comment
У меня отлично работает. Возможно, проблемы с брандмауэром или маршрутизацией?   -  person mekwall    schedule 03.01.2013
comment
Привет, Маркус, вы можете получать многоадресные сообщения сервера после подписки на 230.185.192.108?   -  person Taurian    schedule 03.01.2013
comment
Ага. Я пробовал это только локально на той же машине, но клиент получает сообщения. Изменить: стоит отметить, что я использовал порт 61088 вместо 8088 из-за привилегий.   -  person mekwall    schedule 03.01.2013
comment
Я сменил client.addMembership ('230.185.192.108'); в client.addMembership ('230.185.192.108', 'HOST'); и, похоже, это сделало это. Я тоже все делаю локально. Привет, спасибо еще раз за всю помощь, Маркус.   -  person Taurian    schedule 03.01.2013
comment
В вашем заголовке написано многоадресная передача, но в вашем вопросе говорится о трансляции. Что он?   -  person user207421    schedule 20.11.2016
comment
Я обнаружил привязку слушателя к многоадресному адресу - например, client.bind(PORT, '230.185.192.108') - сработало. Мне не нужно было указывать HOST в вызове addMembership(). (Запуск обоих процессов на одном хосте, fwiw.)   -  person broofa    schedule 08.04.2020
comment
Ваш клиент привязан к хосту и порту, ожидая сообщений. Ваш сервер инициирует связь, отправляя исходные сообщения. Эти представления о клиенте и сервере кажутся мне семантически перевернутыми.   -  person Wyck    schedule 20.03.2021


Ответы (2)


Изменено:

client.addMembership('230.185.192.108');

to

client.addMembership('230.185.192.108',HOST); //Local IP Address
person Taurian    schedule 03.01.2013
comment
как это работает? Если HOST не указан, ОС должна попытаться выполнить привязку ко всем применимым интерфейсам, поэтому, указав только один HOST, мы ограничиваем только те интерфейсы, с которыми ОС будет связывать , Правильно? - person Willem Mulder; 28.10.2014
comment
Если HOST не указан, он выбирает один случайным образом: github.com/nodejs/node / pull / 7244 / files - person Segfault; 01.09.2016
comment
@WillemMulder Вы думаете о TCP. Многоадресная рассылка UDP так не работает. Это не привязка TCP, это присоединение к группе многоадресной рассылки UDP. - person user207421; 20.11.2016
comment
@EJP Да, это UDP, и группа обычно присоединяется к определенному интерфейсу (определяется установкой переменной HOST). Мне было интересно, как сделать addMembership более ограничительным, чтобы исправить эту проблему, но Segfault указал, что отсутствие переменной HOST привязывается не ко всем интерфейсам, а к одному интерфейсу случайным образом. Это странное поведение, и поэтому указание HOST решает проблему, потому что теперь поведение становится предсказуемым. - person Willem Mulder; 21.11.2016

Это старый ответ, но он часто встречается в результатах поиска Google. В Node v4.4.3 пример сервера завершается ошибкой EBADF. Полный рабочий блок кода приведен ниже:

Сервер:

//Multicast Server sending messages
var news = [
   "Borussia Dortmund wins German championship",
   "Tornado warning for the Bay Area",
   "More rain for the weekend",
   "Android tablets take over the world",
   "iPad2 sold out",
   "Nation's rappers down to last two samples"
];

var PORT = 41848;
var MCAST_ADDR = "230.185.192.108"; //not your IP and should be a Class D address, see http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
var dgram = require('dgram'); 
var server = dgram.createSocket("udp4"); 
server.bind(PORT, function(){
    server.setBroadcast(true);
    server.setMulticastTTL(128);
    server.addMembership(MCAST_ADDR);
});

setInterval(broadcastNew, 3000);

function broadcastNew() {
    var message = new Buffer(news[Math.floor(Math.random()*news.length)]);
    server.send(message, 0, message.length, PORT,MCAST_ADDR);
    console.log("Sent " + message + " to the wire...");
}

Клиент:

//Multicast Client receiving sent messages
var PORT = 41848;
var MCAST_ADDR = "230.185.192.108"; //same mcast address as Server
var HOST = '192.168.1.9'; //this is your own IP
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.setMulticastTTL(128); 
    client.addMembership(MCAST_ADDR);
});

client.on('message', function (message, remote) {   
    console.log('MCast Msg: From: ' + remote.address + ':' + remote.port +' - ' + message);
});

client.bind(PORT, HOST);

Для новичков вроде меня client.bind(PORT,HOST); - важный момент. Я не мог заставить клиента получать что-либо при привязке к HOST=127.0.0.1, но работал, когда использовался IP-адрес. Опять же, если HOST исключен, пример не будет работать при тестировании на одной машине (клиент выдаст ошибку EADDRINUSE)

person Abhijit Karnik    schedule 31.03.2017
comment
Измените dgram.createSocket('udp4') на dgram.createSocket({ type: 'udp4', reuseAddr: true }), и вы сможете удалить переменную HOST и избавиться от ошибки EADDRINUSE на одной машине. - person seelts; 28.01.2018