节点中 socket.send() 上的 EADDRNOTAVAIL 错误(SSDP 协议)
Error EADDRNOTAVAIL on socket.send() in node (SSDP protocol)
我正在尝试实现一个 UPnP 发现服务工具(SSDP 协议),我在 python 中做了类似的事情 post: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
});
});
我怀疑这是一个典型的单行问题,但过了一会儿我找不到了,欢迎任何帮助。
我看到了,在节点中 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 设备响应,没有显式套接字绑定。
为了它的价值,我在 Windows 上使用节点 10 进行了类似的设置,并在本地主机上创建了一个 udp4
套接字。奇怪的是,在我的 CI 测试中,接受的答案中描述的设置适用于每个 OS 和节点版本 除了 Windows 上的节点 10。为了使事情正常进行,我必须显式绑定到地址 localhost
而不是 0.0.0.0
,如下所示:
const socket = dgram.createSocket('udp4').unref();
socket.bind({
address: 'localhost',
port: 0
}, (err) => {
!!err && console.error(err);
});
我正在尝试实现一个 UPnP 发现服务工具(SSDP 协议),我在 python 中做了类似的事情 post: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
});
});
我怀疑这是一个典型的单行问题,但过了一会儿我找不到了,欢迎任何帮助。
我看到了,在节点中 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 设备响应,没有显式套接字绑定。
为了它的价值,我在 Windows 上使用节点 10 进行了类似的设置,并在本地主机上创建了一个 udp4
套接字。奇怪的是,在我的 CI 测试中,接受的答案中描述的设置适用于每个 OS 和节点版本 除了 Windows 上的节点 10。为了使事情正常进行,我必须显式绑定到地址 localhost
而不是 0.0.0.0
,如下所示:
const socket = dgram.createSocket('udp4').unref();
socket.bind({
address: 'localhost',
port: 0
}, (err) => {
!!err && console.error(err);
});