当前位置: 移动技术网 > IT编程>脚本编程>NodeJs > Node.js API详解之 dgram模块用法实例分析

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

2020年06月14日  | 移动技术网IT编程  | 我要评论

本文实例讲述了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程序设计有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网