欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-09-06 23:30:34
本文实例讲述了node.js api详解之 dgram模块用法。分享给大家供大家参考,具体如下:node.js api详解之 dgramdgram模块提供了 udp 数据包 socket 的实现。使用...

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