1.什么是UDP?这里简单介绍一下。UDP,即UserDatagramProtocol,是一种无连接的传输层协议,提供不可靠的消息传递服务。UDP协议使用端口号为不同的应用预留自己的数据传输通道是非常重要的。与TCP相比,占用资源少,传输速度快。2、理解UDP单播、广播和组播单播:当向单播地址发送UDP数据报时,该数据报只能被指定的IP主机接收,同一子网下的其他主机不会接收到该数据报。单播进程(假设子网地址:192.168.10,该子网下有两台主机:192.168.10.2、192.168.10.3,向192.168.10.2发送数据报)向主机192.168.10.2的8060端口发送数据报,目标IP为IP数据报在以太网中通过ARP解析成MAC地址,然后将MAC地址设置为目标地址发送出去。当子网下的主机以太网接口看到数据帧时,比较自己的MAC地址,如果不同则忽略数据帧。当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发送数据报):数据报到192.168.10.255,主机端口为8060。IP数据报的目标IP在以太网中通过ARP解析成MAC地址,然后将这个MAC地址设置为目标地址发送出去。192.168.10.2和192.168.10.3的主机接口都将成功匹配广播地址。当数据报进入传输层时,根据端口是否匹配来判断是否丢弃数据。如果端口是8060,数据会被保留,否则数据会被丢弃。组播:向一个组播地址发送UDP数据报,该组网络下的所有主机都会受到影响,主机会根据端口号判断是否丢弃该数据。组播过程的原理与广播类似。3.dgram模块API介绍该模块用于创建UDP数据报套接字,继承了EventEmitter。本模块API如下:3.1UDP单播实现server:constdgram=require("dgram"),server=dgram.createSocket("udp4");server.on("close",()=>{console.log("sockethasbeenclosed");})server.on("error",(err)=>{console.log(err);})server.on("listening",()=>{console.log("socketislistening...");})server.on("message",(msg,rinfo)=>{console.log(`来自客户端${rinfo.address}的消息:${rinfo.port}-${msg}`);server.send(`欢迎${rinfo.address}:${rinfo.port}`,rinfo.port,rinfo.address);setTimeout(function(){server.send(`exit`,rinfo.port,rinfo.address);},2000);})server.bind(8060)客户端:constdgram=require("dgram"),client=dgram.createSocket("udp4");client.on("close",()=>{console.log("sockethasbeenclosed");})client.on("error",(err)=>{console.log(err);})client.on("listening",()=>{console.log("socketislistening");})client.on("消息",(msg,rinfo)=>{if(msg=="退出"){client.close();}console.log(`来自服务器${rinfo.address}的消息:${rinfo.port}-${msg}`);})client.send(`hello`,8060,'127.0.0.1');3.2UDP广播的实现要实现UDP广播,必须要知道广播地址,如何计算广播地址呢?可以使用ipconfig(windows)或ifconfig(*unix)获取ip地址和mask地址,然后使用ip地址和mask子网掩码获取网络地址。网络地址中的主机位为1,即广播地址。例如:IP:149.88.160.58mask:11111111.11111111.11000000.00000000IP&MASK得到网络地址:149.88.128.0/18网络号是主机位全为0,即149.88.10000000.000008000000000000000000000000000000000000000000000000000000的广播地址这是8个主机位。即149.88.10111111.11111111或149.88.191.255然后实现UDP广播,我机器的IP是192.168.0.193,掩码是255.255.255.0,所以广播地址是192.168.0.255,服务器向广播地址的8061端口发送数据报,客户端端绑定本机8061端口,如下:server:constdgram=require("dgram"),server=dgram.createSocket("udp4");server.on("close",()=>{console.log("socketisclosed...");});server.on("listening",()=>{console.log("socketislistening...");server.setBroadcast(true);server.setTTL(128);setInterval(()=>{server.send("大家好,我是服务器。",8061,"192.168.0.255")},2000)})server.on("message",(msg,rinfo)=>{console.log(`msgfromclient${rinfo.address}:${rinfo.port}`);})server.bind(8060,“192.168.0.193”);客户端:constdgram=require("dgram"),client=dgram.createSocket("udp4");client.on("close",()=>{console.log("socketClosed...");})client.on("error",err=>{console.log(err);})client.on("listening",()=>{console.log("isListen...");})client.on("message",(msg,rinfo)=>{console.log(`msgfromserver:${msg}`);})client.bind(8061,"192.168.0.193")3.3UDP组播实现组播地址是实现UDP组播的关键,所以理解组播地址是重点什么是组播地址?IANA为IP组播分配D类地址(224.0.0.0-239.255.255.255)来标识一个IP组播组,组成员关系由IGMP(GroupManagementProtocol)协议维护,其中:224.0.0.0~224.0。0.255为永久组地址,地址224.0.0.0保留不分配,其他地址由路由协议使用;224.0.1.0~224.0.1.255是可以上网的公网组播地址;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组播,如下:server:constdgram=require('dgram'),server=dgram.createSocket("udp4"),multicastAddr='224.100.100.100';server.on("error",err=>{console.log('socketisclosed');})server.on('error',(err)=>{console.log(err);});server.on("listening",()=>{console.log("socketislistening...");server.addMembership(multicastAddr);server.setMulticastTTL(128);setInterval(()=>{sendMsg();},1500)})server.on('message',(msg,rinfo)=>{console.log(`来自客户端的消息${rinfo.address}:${rinfo.port}`);});functionsendMsg(){server.send('大家好,我是服务器。',8061,multicastAddr);}server.bind(8060);Client:constdgram=require("dgram"),client=dgram.createSocket("udp4"),multicastAddr='224.100.100.100';client.on("close",()=>{console.log("socketisclosed...");})client.on("error",err=>{console.log(err);})client.on("listening",()=>{console.log("socketislistening...");client.addMembership(multicastAddr);})client.on("message",(msg,rinfo)=>{console.log(`msgfromserver:${msg}`);})client.bind(8061)除了UDP网络穿透相关内容,也可以了解CSDN【Nodedgram模块实现UDP通信】同步更新
