使用node进行udp协议扩展
1、简介
UDP(UserDatagramProtocol)是一个简单的面向消息的传输层协议,尽管UDP提供标头和有效负载的完整性验证(通过校验和),但它不保证向上层协议提供消息传递,并且UDP层在发送后不会保留UDP 消息的状态。因此,UDP有时被称为不可靠的数据报协议。如果需要传输可靠性,则必须在用户应用程序中实现。
UDP使用具有最小协议机制的简单无连接通信模型。UDP提供数据完整性的校验和,以及用于在数据报的源和目标寻址不同函数的端口号。它没有握手对话,因此将用户的程序暴露在底层网络的任何不可靠的方面。如果在网络接口级别需要纠错功能,应用程序可以使用为此目的设计的传输控制协议(TCP)。
综上所述:
UDP是基于IP的简单协议,不可靠的协议。
UDP的优点:简单,轻量化。
UDP的缺点:没有流控制,没有应答确认机制,不能解决丢包、重发、错序问题。
这里需要注意一点,并不是所有使用UDP协议的应用层都是不可靠的,应用程序可以自己实现可靠的数据传输,通过增加确认和重传机制,所以使用UDP 协议最大的特点就是速度快。
const dgram = require('dgram');
const server = dgram.createSocket('udp4');
const os = require('os')
const multicastAddress = '239.0.1.244';
server.on('error', (err) => {
console.log(`服务器错误:\n${err.stack}`);
server.close();
});
server.on('message', (msg, rinfo) => {
console.log(`服务器接收到: ${msg} 来自 ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
const address = server.address();
console.log(address);
console.log(`服务器正在监听 ${address.address}:${address.port}`);
});
server.bind(38099,()=>{
server.setBroadcast(true)
server.setMulticastTTL(128)
// 获取所有网络接口
const interfaces = os.networkInterfaces();
// 遍历每个网络接口
Object.keys(interfaces).forEach((interfaceName) => {
const networkInterface = interfaces[interfaceName];
// 遍历接口的每个地址
networkInterface.forEach((address) => {
// 只处理 IPv4 地址和不是回环地址的地址
if (address.family === 'IPv4' && !address.internal) {
// 添加组播成员
server.addMembership(multicastAddress, address.address);
// server.setMulticastInterface(address.address)
console.log(`Added multicast membership: ${address.address} on ${interfaceName}`);
}
});
});
});
注意项:
当使用接受方时,组播地址需要多次调用
使用 IP_ADD_MEMBERSHIP
套接字选项告诉内核在给定的 multicastAddress
和 multicastInterface
上加入多播组。 如果未指定 multicastInterface
参数,则操作系统将选择一个接口并为其添加成员资格。 要为每个可用接口添加成员资格,则多次调用 addMembership
,每个接口一次。
在liunx上可以使用查看个网卡的组播地址
ipmaddr show
当使用发送时注意:
当绑定的ip为0.0.0.0所有网卡时,udp会自动选择路由表中的一个发送,需要显性为每个网卡创建一个随机的udp服务为最好