节点(SSDP协议)中socket.send()上的错误EADDRNOTAVAIL

时间:2018-02-11 16:25:26

标签: node.js udp upnp ssdp

我试图实现UPnP发现服务工具(SSDP协议),我在python之后做了类似的事情:https://www.electricmonk.nl/log/2016/07/05/exploring-upnp-with-python/我希望将它移植到节点(v.8.6。 0)和打字稿但是当我尝试发送消息(socket.send(...))时我收到以下错误:

{ Error: send EADDRNOTAVAIL 239.255.255.250:1900
    at Object._errnoException (util.js:1019:11)
    at _exceptionWithHostPort (util.js:1041:20)
    at SendWrap.afterSend [as oncomplete] (dgram.js:475:11)
  code: 'EADDRNOTAVAIL',
  errno: 'EADDRNOTAVAIL',
  syscall: 'send',
  address: '239.255.255.250',
  port: 1900 }

我找到了一段节点的代码,这使得这个确切的事情(https://coolaj86.com/articles/adventures-in-upnp-with-node-js/)并且我认为我的代码非常相同但是我无法理解为什么我的代码不能正常工作

const dgram = require('dgram');
const socket = dgram.createSocket('udp4');

let msg_txt = 'M-SEARCH * HTTP/1.1\r\n' +
    'HOST:239.255.255.250:1900\r\n' +
    'ST:upnp:rootdevice\r\n' +
    'MX:2\r\n' +
    'MAN:"ssdp:discover"\r\n\r\n';

const message = Buffer.from(msg_txt);

socket.on('message', (msg: Buffer, info: any) => {
    console.log(msg.toString());
});

socket.bind({
    address: '239.255.255.250',
    port: 1900
}, (err) => {
    !!err && console.error(err);
});

socket.on('listening', () => {
    console.log('Sending msg...');
    socket.send(message, 0, message.length, 1900, '239.255.255.250', (err) => {
        !!err && console.error(err); // err != null
    });
});

我怀疑这是一个典型的单行问题,但过了一段时间我无法找到它,欢迎任何帮助。

2 个答案:

答案 0 :(得分:0)

我看到它,在节点中API有点不同,绑定应该是针对'0.0.0.0'iface和端口0(对于一个随机数),所以将绑定命令更改为以下代码只是修复它:

socket.bind({
    address: '0.0.0.0',
    port: 0
}, (err) => {
    !!err && console.error(err);
});

在python中,我调用socket.recvfrom()方法来获取UPnP设备响应,没有明确的套接字绑定。

答案 1 :(得分:0)

对于它的价值,我使用Windows上的Node 10进行了类似的设置,并在localhost上创建了一个udp4套接字。奇怪的是,在我的CI测试中,接受的答案中描述的设置适用于Windows上的所有操作系统和节点版本 Node 10除外。为了使工作正常进行,我必须显式绑定到地址localhost而不是0.0.0.0,就像这样:

const socket = dgram.createSocket('udp4').unref();
socket.bind({
    address: 'localhost',
    port: 0
}, (err) => {
    !!err && console.error(err);
});