【Node dgram模块实现UDP通信】
来源:互联网 发布:积分商城java源代码 编辑:程序博客网 时间:2024/04/24 20:15
1、什么是UDP?
这里简单介绍下,UDP,即用户数据报协议,一种面向无连接的传输层协议,提供不可靠的消息传送服务。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数据报socket,继承了EventEmitter,该模块的API如下所示:
3.1 UDP单播实现
服务端:
const dgram = require("dgram"), 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(`message from client ${rinfo.address}:${rinfo.port}-${msg}`); server.send(`welcome ${rinfo.address}:${rinfo.port}`, rinfo.port, rinfo.address); setTimeout(function () { server.send(`exit`, rinfo.port, rinfo.address); }, 2000);})server.bind(8060)
客户端:
const dgram = require("dgram"), 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) => { if (msg == "exit") { client.close(); } console.log(`message from server ${rinfo.address}:${rinfo.port}-${msg}`);})client.send(`hello`,8060,'127.0.0.1');
3.2 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为192.168.0.193,掩码为255.255.255.0,因此广播地址为192.168.0.255,服务端向广播地址的8061端口发送数据报,客户端绑定本机的8061端口,如下所示:
服务端:
const dgram = require("dgram"), server = dgram.createSocket("udp4");server.on("close", () => { console.log("socket已关闭....");});server.on("listening", () => { console.log("socket正在监听..."); server.setBroadcast(true); server.setTTL(128); setInterval(() => { server.send("大家好啊,我是服务端.", 8061, "192.168.0.255") }, 2000)})server.on("message", (msg, rinfo) => { console.log(`msg from client ${rinfo.address}:${rinfo.port}`);})server.bind(8060,"192.168.0.193");
客户端:
const dgram = require("dgram"), client = dgram.createSocket("udp4");client.on("close",()=>{ console.log("socket已关闭...");})client.on("error",err=>{ console.log(err);})client.on("listening",()=>{ console.log("正在监听...");})client.on("message",(msg,rinfo)=>{ console.log(`msg from server:${msg}`);})client.bind(8061,"192.168.0.193")
3.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'), server = dgram.createSocket("udp4"), multicastAddr = '224.100.100.100';server.on("error",err=>{ 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(`msg from client ${rinfo.address}:${rinfo.port}`);});function sendMsg(){ server.send('大家好啊,我是服务端.',8061,multicastAddr);}server.bind(8060);
客户端:
const dgram = require("dgram"), client = dgram.createSocket("udp4"), 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(`msg from server:${msg}`);})client.bind(8061)
另外UDP内网穿透相关的内容,大家也可自行了解一下。
segmentfault【Node dgram模块实现UDP通信】同步更新
- Node.js:dgram模块实现UDP通信
- 【Node dgram模块实现UDP通信】
- 使用dgram模块实现基于UDP的数据通信
- 12、网络编程之dgram模块(UDP)
- Udp实现通信DEMO
- UDP通信C++实现
- python实现UDP通信
- C++实现UDP通信。。
- Java实现UDP通信
- Android实现UDP通信
- Qt-----实现Udp通信
- UDP通信实现
- socket实现UDP通信
- Java实现UDP通信
- C#实现UDP通信
- 详细分析Node.js中的UDP模块
- Node.js UDP / Datagram Sockets模块
- 【Node.js基础篇】(十)使用net模块和Readline模块实现Socket通信
- Linux的安装过程
- 关于 const 的全面总结 C++
- Java多线程-----第二节:线程池详解
- 51单片机的中断系统(八)串口通信常用的错误校验
- HDOJ2019
- 【Node dgram模块实现UDP通信】
- HDOJ2020
- Java[从菜鸟到高手演变]之JVM内存管理及垃圾回收
- 数据迁移测试方法【转】
- Ajax 菜谱(template引擎)
- LimeSDR + Osmo-TRX + OpenBTS搭建简易GSM基站测试
- bzoj4291 [PA2015]Kieszonkowe
- 缓存管理方案 AutoLoadCache (spring注解管理缓存,可与redis,mencache等对接)
- HDOJ2021