Node.js:dgram模块实现UDP通信

摘要:
当向单播地址发送UDP数据报时,数据报只能由指定的IP主机接收。IP数据报的目标IP地址通过以太网中的ARP解析为MAC地址。当子网下主机的以太网接口看到数据帧时,IP数据报的目标IP地址通过以太网中的ARP解析为MAC地址。192.168.10.2和192.168.10.3的主机接口将成功匹配广播地址。server.on('error';server.on)('listening';

1、什么是UDP?

这里简单介绍下,UDP,即用户数据报协议,一种面向无连接的传输层协议,提供不可靠的消息传送服务。UDP协议使用端口号为不同的应用保留其各自的数据传输通道,这一点非常重要。与TCP相比,占用资源更少,传输速度更快。

2、了解UDP单播、广播和组播

单播:向一个单播地址发送UDP数据报时,数据报只能被指定的IP主机接收,同一子网下的其它主机都不会接收该数据报。单播过程(假设子网地址:192.168.10,该子网下有两台主机:192.168.10.2,192.168.10.3,向192.168.10.2发送数据报)

  1. 向主机192.168.10.2的8060端口发送数据报,该IP数据报目标IP在以太网中被ARP解析成MAC地址,然后将此MAC地址设置为目标地址发出去。
  2. 该子网下的主机以太网接口看到该数据帧时,对比自己的MAC地址,如果不一样,则忽略该数据帧。
  3. 直到192.168.10.2主机看到该数据帧时,发现MAC一致,则读入该数据帧,然后在IP层对比目标IP和本机IP,在UDP层对比端口号是否一致,最后接收该数据帧。

广播:向一个广播地址发送UDP数据报,该广播网络下的所有主机都会受到影响,主机根据端口号来判断是否丢弃该数据。广播过程(假设子网地址:192.168.10,则该网络的广播地址为:192.168.10.255,该子网下有两台主机:192.168.10.2,192.168.10.3,向192.168.10.255发送数据报):

  1. 向192.168.10.255主机端口为8060发送数据报,,该IP数据报目标IP在以太网中被ARP解析成MAC地址,然后将此MAC地址设置为目标地址发出去。
  2. 192.168.10.2和192.168.10.3的主机接口都会和此广播地址匹配成功,直到该数据报进入传输层时根据端口是否匹配判断是否丢弃该数据,端口为8060的会保留该数据,否则将数据丢弃。

广播:向一个组播地址发送UDP数据报,该组网络下的所有主机都会受到影响,主机根据端口号来判断是否丢弃该数据。组播过程原理与广播类似。

3、dgram模块API介绍

该模块用来创建UDP数据报socket,继承了EventEmitter,该模块的API如下所示:
Node.js:dgram模块实现UDP通信第1张

3、UDP单播实现

单播的原理上面已经说了,这里便不再叙述。
服务端:

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

server.on('close',()=>{
	console.log('socket已关闭');
});

server.on('error',(err)=>{
	console.log(err);
});

server.on('listening',()=>{
	console.log('socket正在监听中...');
});

server.on('message',(msg,rinfo)=>{
	console.log(`receive message from ${rinfo.address}:${rinfo.port}`);
	server.send('exit',rinfo.port,rinfo.address)
});

server.bind('8060');

客户端:

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

client.on('close',()=>{
	console.log('socket已关闭');
});

client.on('error',(err)=>{
	console.log(err);
});
client.on('message',(msg,rinfo)=>{
	if(msg=='exit') client.close();
	console.log(`receive message from ${rinfo.address}:${rinfo.port}`);
});
client.send(`hello`,8060,'1.1.1.69');

3、UDP广播实现

要实现UDP广播,就必须知道广播地址,广播地址如何计算呢?可以利用ipconfig(windows)ifconfig(*unix)得到ip地址和mask掩码地址,然后利用ip地址与mask子网掩码做与操作得到网络地址,网络地址中主机位都为1就是广播地址,举个例子:

IP:149.88.160.58
mask:11111111.11111111.11000000.00000000
IP&MASK得到网络地址:149.88.128.0/18
网络号就是主机位全为0,即149.88.10000000.00000000 即149.88.128.0
广播地址就是主机位全为1,即149.88.10111111.11111111即149.88.191.255 

接着实现UDP广播,我机子的IP为1.1.1.69,掩码为255.255.255.0,因此广播地址为1.1.1.255,服务端向广播地址的8061端口发送数据报,客户端绑定本机的8061端口,如下所示:
服务端:


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

server.on('close',()=>{
	console.log('socket已关闭');
});

server.on('error',(err)=>{
	console.log(err);
});

server.on('listening',()=>{
	console.log('socket正在监听中...');
	server.setBroadcast(!0);//开启广播
	server.setTTL(128);
	server.send('大家好啊,我是服务端.',8061,'1.1.1.255');
});

server.on('message',(msg,rinfo)=>{
	console.log(`receive message from ${rinfo.address}:${rinfo.port}`);
});

server.bind('8060','1.1.1.69');

客户端:

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

client.on('close',()=>{
	console.log('socket已关闭');
});

client.on('error',(err)=>{
	console.log(err);
});
client.on('listening',()=>{
	console.log('socket正在监听中...');
});
client.on('message',(msg,rinfo)=>{
	console.log(`receive message from ${rinfo.address}:${rinfo.port}:${msg}`);
});
client.bind(8061,'1.1.1.69');

3、UDP组播实现

组播地址是实现UDP组播的关键,因此了解组播地址是重点。什么是组播地址?IANA将D类地址(224.0.0.0-239.255.255.255)分配给IP组播,用来标识一个IP组播组,由IGMP(组管理协议)协议维护组成员关系,其中:
224.0.0.0~224.0.0.255为永久组地址,地址224.0.0.0保留不做分配,其它地址供路由协议使用;
224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;
224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;
239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。
向组播地址发送数据报,只有该组成员才会接收此数据报。
dgram模块的addMembership()方法将socket加入组播组中,dropMembership()方法退出组播组。下面以组播地址224.100.100.100来实现UDP组播,如下所示:
服务端:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');
const multicastAddr = '224.100.100.100';

server.on('close',()=>{
	console.log('socket已关闭');
});

server.on('error',(err)=>{
	console.log(err);
});

server.on('listening',()=>{
	console.log('socket正在监听中...');
	server.addMembership(multicastAddr);
	server.setMulticastTTL(128);
	setInterval(()=>{
		sendMsg();
	},1500);
});

server.on('message',(msg,rinfo)=>{
	console.log(`receive message from ${rinfo.address}:${rinfo.port}`);
});

function sendMsg(){
	server.send('大家好啊,我是服务端.',8061,multicastAddr);
}

server.bind('8060','1.1.1.69');

客户端:

const dgram = require('dgram');
const client = dgram.createSocket('udp4');
const multicastAddr = '224.100.100.100';

client.on('close',()=>{
	console.log('socket已关闭');
});

client.on('error',(err)=>{
	console.log(err);
});
client.on('listening',()=>{
	console.log('socket正在监听中...');
	client.addMembership(multicastAddr);
});
client.on('message',(msg,rinfo)=>{
	console.log(`receive message from ${rinfo.address}:${rinfo.port}:${msg}`);
});
client.bind(8061,'1.1.1.69');

另外UDP内网穿透相关的内容,大家也可自行了解一下。

免责声明:文章转载自《Node.js:dgram模块实现UDP通信》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【初次使用h0遇到的一些问题】前端导出功能实现的两种方式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

VxWorks固件分析方法总结

VxWorks固件分析方法总结 最近研究基于VxWorks系统的iot设备的固件分析方法,将学习心得记录于此,以备将来的查询需要。 1.VxWorks是什么? VxWorks是美国WindRiverSystem公司(风河公司)推出的一个RTOS(实时操作系统),凭借良好的持续发展能力、高性能的内核以及友好的用户开发环境,在嵌入式实时操作系统领域占据一席之地...

如何使用 window.open() 下载文件: 在本页面打开并防止浏览器拦截

下载文件时,接口请求返回内容一般有两种: 直接返回文件内容,返回一个url 用window.open()直接打开请求地址或者返回的url,可能会因为跨域问题导致浏览器拦截 解决办法是:在请求前,打开一个窗口,然后将请求地址或者返回的url直接赋值给该窗口的href 1. 直接返回文件内容: 打开请求api地址 downPkg() { let...

32位程序调用64位函数————开源代码rewolf-wow64ext学习笔记

rewolf-wow64ext的目的就是让运行在Wow64环境中的x86应用程序可以直接调用x64下ntdll.dll中的Native API。   学习中可以得到几个结论 在X64环境下的进程,32位程序,映射了两个地址空间,一个32位,一个64位。而且这两种工作模式是可以切换的的。 WOW64进程中的R12寄存器指向其64位的TEB结构(线程环境块...

SAP 如何修改已有字段的文本描述(如将销售员改为业务员)

SAP系统中有许多用户使用不上字段,而一些用户想要的字段有的没有。大家可以修改一些用不到字段的显示名称,作为自己的使用字段; 如:BP客户主数据 中没有中国标准的行政区划代码,现在需要将“地址-邮政信箱地址”下的“邮政编码”改为“行政区划” 1、输入BP,进入客商维护主数据页面,在要修改的字段上按F1,查到(地址-邮政信息地址-邮政编码)字段的字段名POS...

漫谈 IP 协议

IP数据报格式 IP地址分类 IPV4简单粗暴地把IP地址分为五类。分类方法如下图: 之所以要划分IP地址,目的是为区分不同的组织机构——A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳的地址数目不同。对于使用者本身,使用的是A/B/C哪一类,倒没有区别。 A、B、C三类IP地址的特征:当将...

阿里云更改域名解析的 IP 地址

前言 由于之前事比较多,阿里的 ECS 过期了,重新买了个学生服务器,这里记录更改域名解析的 IP 地址。 步骤 打开 “域名服务 -> 域名列表” ,点击要修改信息的域名的 “解析” 。 分别点击 “www” 和 “@” 两项的 “修改” ,并修改其中的 “记录值” 为新的 IP 地址。 可以在等待一段时间后,通过 ping 命令查...