Node中socket.send()报Error EADDRNOTAVAIL错误(SSDP协议场景)
Hey there! Let's tackle that EADDRNOTAVAIL error you're running into when porting your SSDP/UPnP discovery tool from Python to Node.js + TypeScript. That error almost always means your socket is trying to use an IP address your system can't access—super common when dealing with broadcast protocols like SSDP.
Common Causes & Fixes
Let's break down the most likely issues and how to fix them:
Incorrect Binding Address
If you're binding your UDP socket to a specific local IP (like127.0.0.1or a hardcoded NIC IP that's not active), Node.js will throwEADDRNOTAVAILwhen trying to send broadcast traffic. SSDP requires your socket to listen on all available network interfaces.- Fix: Bind to
0.0.0.0instead of a specific IP. This lets the socket use any active network interface.
- Fix: Bind to
Missing Broadcast Permission
UDP sockets in Node.js don't allow broadcast by default. If you forget to enable this, sending to the SSDP broadcast address will fail.- Fix: Call
socket.setBroadcast(true)right after creating the socket.
- Fix: Call
Invalid Target Address
Double-check you're sending to the standard SSDP broadcast address:239.255.255.250on port1900. Using any other address will cause issues.
Working TypeScript Example
Here's a cleaned-up, TS-compatible implementation that addresses these issues, adapted for Node.js v8.6.0+:
import * as dgram from 'dgram'; // SSDP standard constants const SSDP_BROADCAST_ADDR = '239.255.255.250'; const SSDP_PORT = 1900; const SSDP_SEARCH_MSG = `M-SEARCH * HTTP/1.1 HOST: ${SSDP_BROADCAST_ADDR}:${SSDP_PORT} MAN: "ssdp:discover" MX: 3 ST: ssdp:all`; // Create UDP socket const socket = dgram.createSocket('udp4'); // Enable broadcast support socket.setBroadcast(true); // Bind to all interfaces (0.0.0.0) and let Node pick a random port socket.bind(() => { console.log('Socket bound, sending SSDP discovery message...'); // Send the search request socket.send( SSDP_SEARCH_MSG, 0, SSDP_SEARCH_MSG.length, SSDP_PORT, SSDP_BROADCAST_ADDR, (err) => { if (err) { console.error('Failed to send SSDP message:', err); socket.close(); return; } // Listen for responses from UPnP devices socket.on('message', (msg, rinfo) => { console.log(`\nResponse from ${rinfo.address}:${rinfo.port}:`); console.log(msg.toString()); }); // Close socket after MX timeout (3 seconds as defined in the message) setTimeout(() => { console.log('\nClosing socket after discovery timeout'); socket.close(); }, 3000); } ); }); // Handle socket errors gracefully socket.on('error', (err) => { console.error('Socket error occurred:', err); socket.close(); });
Key Notes for Node.js v8.6.0
- Node.js v8+ supports all the UDP socket methods used here, so you won't run into compatibility issues.
- For TypeScript, make sure you have
@types/nodeinstalled (npm install @types/node --save-dev) to get proper type definitions for thedgrammodule.
Additional Checks
If you still see the error after applying these fixes:
- Verify your system's firewall isn't blocking UDP traffic on port 1900.
- Check that your active network interfaces allow broadcast traffic (some VPNs or restricted networks disable this).
- Ensure you're not running another process that's monopolizing the SSDP port (though we're using a random port for sending, so this is less likely).
内容的提问来源于stack exchange,提问作者Roberto

