资讯专栏INFORMATION COLUMN

【Node dgram模块实现UDP通信】

lijy91 / 3391人阅读

摘要:组播向一个组播地址发送数据报,该组网络下的所有主机都会受到影响,主机根据端口号来判断是否丢弃该数据。向组播地址发送数据报,只有该组成员才会接收此数据报。模块的方法将加入组播组中,方法退出组播组。模块实现通信同步更新

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内网穿透相关的内容,大家也可自行了解一下。

CSDN【Node dgram模块实现UDP通信】同步更新

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88705.html

相关文章

  • python网络编程

    摘要:在任何类型的通信开始之前,网络应用程序必须创建套接字。基于文件的套接字,家族名又名基于网络的套接字,家族名在和后续的版本中,支持的套接字有,,,。中的网络编程在中主要是用模块来实现基于套接字的网络通信。 python学习记录--网络编程 1、套接字介绍 一台机器上的不同进程之间进行通信可以利用队列,管道等,但是不同机器之间的进程进行通信用队列是不行的,解决这个问题就是网络套接字。 套接...

    xuhong 评论0 收藏0
  • 深入浅出nodeJS - 4 - (玩转进程、测试、产品化)

    摘要:进程间通信的目的是为了让不同的进程能够互相访问资源,并进程协调工作。这个过程的示意图如下端口共同监听集群稳定之路进程事件自动重启负载均衡状态共享模块工作原理事件二测试单元测试性能测试三产品化项目工程化部署流程性能日志监控报警稳定性异构共存 内容 9.玩转进程10.测试11.产品化 一、玩转进程 node的单线程只不过是js层面的单线程,是基于V8引擎的单线程,因为,V8的缘故,前后...

    henry14 评论0 收藏0
  • python大佬养成计划----socket实现UDP通信

    摘要:是建立可靠连接,并且通信双方都可以以流的形式发送数据。相对,则是面向无连接的协议。测试结果用两个命令行分别启动服务器和客户端测试开启服务端完成一次通信 UDP TCP是建立可靠连接, 并且通信双方都可以以流的形式发送数据。 相对TCP, UDP则是面向无连接的协议。使用UDP协议时, 不需要建立连接, 只需要知道对方的IP地址和端口号, 就可以直接发数据包。 但是, 能不能到达就不知道...

    Juven 评论0 收藏0
  • 通过源码解析 Node.js 中进程间通信中的 socket 句柄传递

    摘要:子进程使用反序列化消息字符串为消息对象。在调用这类方法时,遍历列表中的实例发送内部消息,子进程列表中的对应项收到内部消息并处理返回,父进程中再结合返回结果和对应着这个类实例维护的信息,保证功能的正确性。 在 Node.js 中,当我们使用 child_process 模块创建子进程后,会返回一个 ChildProcess 类的实例,通过调用 ChildProcess#send(mess...

    HackerShell 评论0 收藏0
  • Python 网络编程之 UDP 协议

    摘要:创建创建通信接受套接字的数据,与类似,但返回值是。发送数据,将数据发送到,形式为,指定远程地址发送,返回值是发送的字节数发送的报文是类型,发送的报文是类型,在发送前要记得编码。 UDP 和 TCP 的区别   TCP UDP 连接性 面向连接 面向无连接 传输可靠性 可靠 不可靠 传输模式 流 数据报 应用场景 传输大量的数据 少量数据 速度 慢 快 T...

    waterc 评论0 收藏0

发表评论

0条评论

lijy91

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<