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

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

以上是 Node.js API详解之 dgram模块用法实例分析 的全部内容, 来源链接: utcz.com/z/351788.html

回到顶部