Node.js API详解之 dgram模块用法实例分析


Posted in Javascript onJune 05, 2020

本文实例讲述了Node.js API详解之 dgram模块用法。分享给大家供大家参考,具体如下:

Node.js API详解之 dgram

dgram模块提供了 UDP 数据包 socket 的实现。

使用以下方式引用:

const dgram = require('dgram');

dgram.createSocket(options[, callback])

说明:

创建一个 dgram.Socket 对象. 一旦创建了套接字,调用 socket.bind() 会指示套接字开始监听数据报消息。
如果 address 和 port 没传给 socket.bind(),
那么这个方法会把这个套接字绑定到 “全部接口” 地址的一个随机端口(这适用于 udp4 和 udp6 套接字)。
绑定的地址和端口可以通过 socket.address().address 和socket.address().port 来获取
options:
type:套接字族. 必须是 ‘udp4' 或 ‘udp6'. 必需填.
reuseAddr:若设置为 true socket.bind() ,则会 重用地址,即时另一个进程已经在其上面绑定了一个套接字。 默认是 false.
recvBufferSize: 设置 SO_RCVBUF 套接字值。
sendBufferSize: 设置 SO_SNDBUF 套接字值。
lookup:惯常的查询函数. 默认是 dns.lookup()。
callback:为 ‘message' 事件绑定一个监听器。可选。

demo:

const dgram = require('dgram');
const server = dgram.createSocket({type: 'udp4'}, () => {
 console.log(`服务器收到:${msg} 来自 ${rinfo.address}:${rinfo.port}`);
});
server.bind(41234);
// 服务器监听 0.0.0.0:41234

dgram.createSocket(type[, callback])

说明:

创建一个特定 type 的dgram.Socket 对象。type参数是udp4 或 udp6。
可选传一个回调函数,作为 ‘message' 事件的监听器。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4', () => {
 console.log(`服务器收到:${msg} 来自 ${rinfo.address}:${rinfo.port}`);
});
server.bind(41234);

dgram.Socket 类

说明:

dgram.Socket对象是一个封装了数据包函数功能的EventEmitter。
dgram.Socket实例是由dgram.createSocket()创建的。
创建dgram.Socket实例不需要使用new关键字。

socket.bind([port][, address][, callback])

说明:

对于 UDP socket,该方法会令dgram.Socket在指定的port和可选的address上监听数据包信息。
若port未指定或为 0,操作系统会尝试绑定一个随机的端口。
若address未指定,操作系统会尝试在所有地址上监听。
绑定完成时会触发一个'listening'事件,并会调用callback方法。
注意,同时监听'listening'事件和在socket.bind()方法中传入callback参数并不会带来坏处,但也不是很有用。
一个被绑定的数据包 socket 会令 Node.js 进程保持运行以接收数据包信息。
若绑定失败,一个'error'事件会被触发。在极少数的情况下(例如尝试绑定一个已关闭的 socket),一个 Error 会被抛出。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4', () => {
 console.log(`服务器收到:${msg} 来自 ${rinfo.address}:${rinfo.port}`);
});
server.bind(41234, () => {
 const address = server.address();
 console.log(`服务器监听 ${address.address}:${address.port}`);
});
// 服务器监听 0.0.0.0:41234

socket.bind(options[, callback])

说明:

options:{port:”, address: ”, exclusive: ”}
对于 UDP socket,该方法会令dgram.Socket在指定的port和可选的address上监听数据包信息。
若port未指定或为 0,操作系统会尝试绑定一个随机的端口。
若address未指定,操作系统会尝试在所有地址上监听。
绑定完成时会触发一个'listening'事件,并会调用callback方法。
在配合cluster模块使用dgram.Socket对象时,options对象可能包含一个附加的exclusive属性。
当exclusive被设为false(默认值)时,集群工作单元会使用相同的 socket 句柄来共享连接处理作业。
当exclusive被设为true时,该句柄将不会被共享,而尝试共享端口则会造成错误。
一个绑定的数据报 socket 会使 Node.js 进程持续运行以接受数据报消息。
如果绑定失败,一个 ‘error' 事件会产生。在极少数情况下(例如尝试绑定一个已经关闭的 socket), 一个 Error 可能抛出。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4', () => {
 console.log(`服务器收到:${msg} 来自 ${rinfo.address}:${rinfo.port}`);
});
server.bind({port: 41234}, () => {
 const address = server.address();
 console.log(`服务器监听 ${address.address}:${address.port}`);
});
// 服务器监听 0.0.0.0:41234

listening 事件

说明:

当一个 socket 开始监听数据包信息时,'listening'事件将被触发。
该事件会在创建 UDP socket 之后被立即触发。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4', () => {
 console.log(`服务器收到:${msg} 来自 ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
 const address = server.address();
 console.log(`服务器监听 ${address.address}:${address.port}`);
});
server.bind({port: 41234});
// 服务器监听 0.0.0.0:41234

error 事件

说明:

当有任何错误发生时,'error'事件将被触发。
事件发生时,事件处理函数仅会接收到一个 Error 参数。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');
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.address}:${address.port}`);
});
server.bind({port: 41234});

message 事件

说明:

当有新的数据包被 socket 接收时,'message'事件会被触发。
msg和rinfo会作为参数传递到该事件的处理函数中。
msg:消息
rinfo:远程地址信息
address:发送方地址
family: 地址类型 (‘IPv4' or ‘IPv6')
port: 发送者端口
size: 消息大小

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('message', (msg, rinfo) => {
 console.log(`服务器收到:${msg} 来自 ${rinfo.address}:${rinfo.port}`);
});
server.on('listening', () => {
 const address = server.address();
 console.log(`服务器监听 ${address.address}:${address.port}`);
});
server.bind({port: 41234});

socket.getRecvBufferSize()

说明:

socket 接收到的字节大小。

demo:

server.on('message', (msg, rinfo) => {
 console.log(`服务器收到字节数:${socket.getRecvBufferSize()}`);
});

socket.setRecvBufferSize(size)

说明:

设置 SO_RCVBUF 套接字选项。设置最大的套接字接收缓冲字节。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.setRecvBufferSize(1024);
server.on('message', (msg, rinfo) => {
 console.log(`服务器收到字节数:${socket.getRecvBufferSize()}`);
});
server.bind({port: 41234});

socket.send(msg, [offset, length,] port [, address] [, callback])

说明:

在 socket 上发送一个数据包。目标port和address须被指定。
msg参数包含了要发送的消息。根据消息的类型可以有不同的做法。
如果msg是一个Buffer 或 Uint8Array,则offset和length指定了消息在Buffer中对应的偏移量和字节数。
如果msg是一个String,那么它会被自动地按照utf8编码转换为Buffer。
对于包含了多字节字符的消息,offset和length会根据对应的byte length进行计算,而不是根据字符的位置。
如果msg是一个数组,那么offset和length必须都不能被指定。
address参数是一个字符串。若address的值是一个主机名,则 DNS 会被用来解析主机的地址。
若address未提供或是非真值,则'127.0.0.1'(用于 udp4 socket)或'::1'(用于 udp6 socket)会被使用。
若在之前 socket 未通过调用bind方法进行绑定,socket 将会被一个随机的端口号赋值并绑定到“所有接口”的地址上(对于udp4 socket 是'0.0.0.0',对于udp6 socket 是'::0')。
可以指定一个可选的callback方法来汇报 DNS 错误或判断可以安全地重用buf对象的时机。
注意,在 Node.js 事件循环中,DNS 查询会对发送造成至少 1 tick 的延迟。
确定数据包被发送的唯一方式就是指定callback。若在callback被指定的情况下有错误发生,该错误会作为callback的第一个参数。
若callback未被指定,该错误会以'error'事件的方式投射到socket对象上。
偏移量和长度是可选的,但如其中一个被指定则另一个也必须被指定。
另外,他们只在第一个参数是Buffer 或 Uint8Array 的情况下才能被使用。

demo:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');
const buf1 = Buffer.from('Some ');
const buf2 = Buffer.from('bytes');
server.on('error', (err) => {
 console.log(`服务器异常:\n${err.stack}`);
 server.close();
});
server.on('message', (msg, rinfo) => {
 console.log(`服务器收到字节数:${socket.getRecvBufferSize()}`);
});
server.on('listening', () => {
 const address = server.address();
 console.log(`服务器监听 ${address.address}:${address.port}`);
});
server.send([buf1, buf2], 8080, 'localhost');
server.bind({port: 41234});

socket.getSendBufferSize()

说明:

socket 发送的字节大小。

demo:

server.send([buf1, buf2], 8080, 'localhost', () => {
 console.log('发送消息字节数:', server.getSendBufferSize());
});

socket.setSendBufferSize(size)

说明:

设置 SO_SNDBUF 套接字选项。设置最大的套接字发送缓冲字节。

demo:

const socket = dgram.createSocket('udp6');
socket.bind(1234, () => {
 socket.setSendBufferSize(1024);
});

socket.unref()

说明:

默认情况下,绑定一个 socket 会在 socket 运行时阻止 Node.js 进程退出。
socket.unref() 方法用于将 socket 从维持 Node.js 进程的引用列表中解除。
可以使用 socket.ref() 再次激活。
socket.unref() 方法返回一个对 socket 的引用,所以可以链式调用。

demo:

const dgram = require('dgram');
const socket = dgram.createSocket('udp6');
socket.bind(1234, () => {
 socket.unref();
});

socket.ref()

说明:

默认情况下,绑定一个 socket 会在 socket 运行时阻止 Node.js 进程退出。
socket.unref() 方法用于将 socket 从维持 Node.js 进程的引用列表中解除。
socket.ref() 方法用于将 socket 重新添加到这个引用列表中,并恢复其默认行为。
多次调用 socket.ref() 不会有额外的作用。
socket.ref() 方法返回一个对 socket 的引用,所以可以链式调用。

demo:

const dgram = require('dgram');
const socket = dgram.createSocket('udp6');
socket.bind(1234, () => {
 socket.unref();
 socket.ref()
});

socket.close([callback])

说明:

关闭该 socket 并停止监听其上的数据。
如果提供了一个回调函数,它就相当于为'close'事件添加了一个监听器。

demo:

const dgram = require('dgram');
const socket = dgram.createSocket('udp6');
socket.bind(1234);
socket.close(() => {
 console.log('socket 已关闭');
});
// socket 已关闭

close 事件

说明:

‘close'事件将在使用close()关闭一个 socket 之后触发。
该事件一旦触发,这个 socket 上将不会触发新的'message'事件。

demo:

const dgram = require('dgram');
const socket = dgram.createSocket('udp6');
socket.bind(1234);
socket.on('close', () => {
 console.log('socket 已关闭');
})
socket.close();
// socket 已关闭

socket.address()

说明:

返回一个包含 socket 地址信息的对象。
对于 UDP socket,该对象将包含address、family和port属性。

demo:

server.on('listening', () => {
 const address = server.address();
 console.log(`服务器监听 ${address.address}:${address.port}`);
});

socket.addMembership(multicastAddress[, multicastInterface])

说明:

通知内核将multicastAddress和multicastInterface提供的多路传送集合通过IP_ADD_MEMBERSHIP这个 socket 选项结合起来。
若multicastInterface参数未指定,操作系统将会选择一个接口并向其添加成员。
要为所有可用的接口添加成员,可以在每个接口上调用一次addMembership方法。

socket.dropMembership(multicastAddress[, multicastInterface])

说明:

引导内核通过IP_DROP_MEMBERSHIP这个 socket 选项删除multicastAddress指定的多路传送集合。
当 socket 被关闭或进程被终止时,该方法会被内核自动调用,所以大多数的应用都不用自行调用该方法。
若multicastInterface未指定,操作系统会尝试删除所有可用接口上的成员。

socket.setBroadcast(flag)

说明:

设置或清除 SO_BROADCAST socket 选项。
当设置为 true, UDP包可能会被发送到一个本地接口的广播地址

socket.setMulticastLoopback(flag)

说明:

设置或清除 IP_MULTICAST_LOOP socket 选项。当设置为 true, 多播数据包也将在本地接口接收。

socket.setMulticastTTL(ttl)

说明:

设置IP_MULTICAST_TTL套接字选项。 一般来说,TTL表示”生存时间”。这里特指一个IP数据包传输时允许的最大跳步数,尤其是对多播传输。
当IP数据包每向前经过一个路由或网关时,TTL值减1,若经过某个路由时,TTL值被减至0,便不再继续向前传输。
传给 socket.setMulticastTTL() 的参数是一个范围为0-255的跳步数。大多数系统的默认值是 1 ,但是可以变化。

socket.setTTL(ttl)

说明:

设置 IP_TTL 套接字选项。 一般来说,TTL表示”生存时间”,这里特指一个IP数据包传输时允许的最大跳步数。
当IP数据包每向前经过一个路由或网关时,TTL值减1,若经过某个路由时,TTL值被减至0,便不再继续向前传输。
比较有代表性的是,为了进行网络情况嗅探或者多播而修改TTL值。
传给 socket.setTTL() 的参数是一个范围为0-255的跳步数。大多数系统的默认值是 1 ,但是可以变化。

希望本文所述对大家node.js程序设计有所帮助。

Javascript 相关文章推荐
javascript RadioButtonList获取选中值
Apr 09 Javascript
Jquery创建一个层当鼠标移动到层上面不消失效果
Dec 12 Javascript
JS根据年月获得当月天数的实现代码
Jul 03 Javascript
禁止iframe脚本弹出的窗口覆盖了父窗口的方法
Sep 06 Javascript
node.js中的http.createServer方法使用说明
Dec 14 Javascript
jQuery中:only-child选择器用法实例
Jan 03 Javascript
AngularJS学习笔记之TodoMVC的分析
Feb 22 Javascript
JavaScript给url网址进行encode编码的方法
Mar 18 Javascript
Three.js 再探 - 写一个微信跳一跳极简版游戏
Jan 04 Javascript
vue实现未登录跳转到登录页面的方法
Jul 17 Javascript
微信小程序实现打开并下载服务器上面的pdf文件到手机
Sep 20 Javascript
vue 数据双向绑定的实现方法
Mar 04 Vue.js
taro 实现购物车逻辑的实例代码
Jun 05 #Javascript
Node.js API详解之 V8模块用法实例分析
Jun 05 #Javascript
Vue CLI4 Vue.config.js标准配置(最全注释)
Jun 05 #Javascript
使用Taro实现小程序商城的购物车功能模块的实例代码
Jun 05 #Javascript
Vue路由的模块自动化与统一加载实现
Jun 05 #Javascript
Jquery滑动门/tab切换实现方法完整示例
Jun 05 #jQuery
详解JS函数防抖
Jun 05 #Javascript
You might like
php设计模式 Visitor 访问者模式
2011/06/28 PHP
php自动识别文件编码并转换为UTF-8的方法
2014/06/12 PHP
php实现最简单的MVC框架实例教程
2014/09/08 PHP
[原创]php实现子字符串位置相互对调互换的方法
2016/06/02 PHP
PHP join()函数用法与实例讲解
2019/03/11 PHP
PHP7 mongoDB扩展使用的方法分享
2019/05/02 PHP
Aster vs KG BO3 第三场2.19
2021/03/10 DOTA
javascript prototype 原型链
2009/03/12 Javascript
很棒的学习jQuery的12个网站推荐
2011/04/28 Javascript
jquery中通过父级查找进行定位示例
2013/06/28 Javascript
一道JS前端闭包面试题解析
2015/12/25 Javascript
Javascript removeChild()删除节点及删除子节点的方法
2015/12/27 Javascript
微信JSAPI支付操作需要注意的细节
2017/01/10 Javascript
setTimeout学习小结
2017/02/08 Javascript
Vue3 的响应式和以前有什么区别,Proxy 无敌?
2020/05/20 Javascript
python笔记(1) 关于我们应不应该继续学习python
2012/10/24 Python
python复制文件的方法实例详解
2015/05/22 Python
python使用rpc框架gRPC的方法
2018/08/24 Python
利用python求积分的实例
2019/07/03 Python
python3发送邮件需要经过代理服务器的示例代码
2019/07/25 Python
css3翻牌翻数字的示例代码
2020/02/07 HTML / CSS
美国学校用品、教室和教学商店:Discount School Supply
2018/04/04 全球购物
小学运动会表扬稿
2014/01/19 职场文书
业务总经理岗位职责
2014/02/03 职场文书
毕业生如何写自我鉴定
2014/03/15 职场文书
产品销售计划书
2014/05/04 职场文书
保护地球的标语
2014/06/17 职场文书
运动会表扬稿范文
2015/05/05 职场文书
校长一岗双责责任书
2015/05/09 职场文书
民主生活会主持词
2015/07/01 职场文书
《认识年月日》教学反思
2016/02/19 职场文书
实习报告范文
2019/07/30 职场文书
MySQL数据库超时设置配置的方法实例
2021/10/15 MySQL
python中的3种定义类方法
2021/11/27 Python
Python pyecharts绘制条形图详解
2022/04/02 Python
Win11筛选键导致键盘失灵怎么解决? Win11关闭筛选键的技巧
2022/04/08 数码科技