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 相关文章推荐
判断客户端浏览器是否安装了Flash插件的多种方法
Aug 11 Javascript
asp.net 30分钟掌握无刷新 Repeater
Sep 16 Javascript
一个JavaScript变量声明的知识点
Oct 28 Javascript
禁止空格提交表单的js代码
Nov 17 Javascript
浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法
Jan 10 Javascript
Jquery原生态实现表格header头随滚动条滚动而滚动
Mar 18 Javascript
调整小数的格式保留小数点后两位
May 14 Javascript
JS监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法
Aug 05 Javascript
vue2.0父子组件间通信的实现方法
Apr 19 Javascript
Vue.js实现价格计算器功能
Mar 30 Javascript
微信小程序实现左滑删除效果
Nov 18 Javascript
详解JS WebSocket断开原因和心跳机制
May 07 Javascript
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程序
2006/10/09 PHP
php公用函数列表[正则]
2007/02/22 PHP
PHP采集类snoopy详细介绍(snoopy使用教程)
2014/06/19 PHP
Win7 64位系统下PHP连接Oracle数据库
2014/08/20 PHP
PHP自定义函数格式化json数据示例
2016/09/14 PHP
php获得文件夹下所有文件的递归算法的简单实例
2016/11/01 PHP
php str_getcsv把字符串解析为数组的实现方法
2017/04/05 PHP
超级兔子让浮动层消失的前因后果
2007/03/09 Javascript
js动态添加onload、onresize、onscroll事件(另类方法)
2012/12/26 Javascript
JS字符串截取函数实例
2013/12/27 Javascript
Node.js编码规范
2014/07/14 Javascript
JavaScript中的方法重载实例
2015/03/16 Javascript
jQuery左侧大图右侧小图焦点图幻灯切换代码分享
2015/08/19 Javascript
用js控件div的滚动条,让它在内容更新时自动滚到底部的实现方法
2016/10/27 Javascript
AngularJS指令用法详解
2016/11/02 Javascript
使用Curl命令查看请求响应时间方法
2016/11/04 Javascript
在 Angular 中实现搜索关键字高亮示例
2017/03/21 Javascript
浅谈express 中间件机制及实现原理
2017/08/31 Javascript
vue和webpack打包项目相对路径修改的方法
2018/06/15 Javascript
了解JavaScript函数中的默认参数
2019/05/30 Javascript
Node使用Nodemailer发送邮件的方法实现
2020/02/24 Javascript
[01:25:09]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第二场
2014/05/24 DOTA
[01:32]2016国际邀请赛中国区预选赛IG战队首日赛后采访
2016/06/27 DOTA
[06:43]2018DOTA2国际邀请赛寻真——VGJ.Thunder
2018/08/11 DOTA
python列表去重的二种方法
2014/02/14 Python
Python之reload流程实例代码解析
2018/01/29 Python
python selenium firefox使用详解
2019/02/26 Python
在pycharm中关掉ipython console/PyDev操作
2020/06/09 Python
泰国最新活动和优惠:Megatix
2020/05/07 全球购物
秋季红领巾广播稿
2014/01/27 职场文书
安全生产网格化管理实施方案
2014/03/01 职场文书
土建专业大学生自荐信范文
2014/04/09 职场文书
小学英语复习计划
2015/01/19 职场文书
关于颐和园的导游词
2015/01/30 职场文书
超详细Python解释器新手安装教程
2021/05/10 Python
Python实现Matplotlib,Seaborn动态数据图
2022/05/06 Python