Node.js v20.11.1 文档


UDP/数据报套接字#

¥UDP/datagram sockets

稳定性: 2 - 稳定的

¥Stability: 2 - Stable

源代码: lib/dgram.js

node:dgram 模块提供了 UDP 数据报套接字的实现。

¥The node:dgram module provides an implementation of UDP datagram sockets.

import dgram from 'node:dgram';

const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.error(`server error:\n${err.stack}`);
  server.close();
});

server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

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

server.bind(41234);
// Prints: server listening 0.0.0.0:41234const dgram = require('node:dgram');
const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.error(`server error:\n${err.stack}`);
  server.close();
});

server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

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

server.bind(41234);
// Prints: server listening 0.0.0.0:41234

类:dgram.Socket#

¥Class: dgram.Socket

封装数据报功能。

¥Encapsulates the datagram functionality.

dgram.Socket 的新实例是使用 dgram.createSocket() 创建的。new 关键字不能用于创建 dgram.Socket 实例。

¥New instances of dgram.Socket are created using dgram.createSocket(). The new keyword is not to be used to create dgram.Socket instances.

事件:'close'#

¥Event: 'close'

在使用 close() 关闭套接字后会触发 'close' 事件。一旦触发,则此套接字上将不会触发新的 'message' 事件。

¥The 'close' event is emitted after a socket is closed with close(). Once triggered, no new 'message' events will be emitted on this socket.

事件:'connect'#

¥Event: 'connect'

'connect' 事件在套接字关联到远程地址作为成功的 connect() 调用的结果之后触发。

¥The 'connect' event is emitted after a socket is associated to a remote address as a result of a successful connect() call.

事件:'error'#

¥Event: 'error'

每当发生任何错误时都会触发 'error' 事件。事件句柄被传入单一的 Error 对象。

¥The 'error' event is emitted whenever any error occurs. The event handler function is passed a single Error object.

事件:'listening'#

¥Event: 'listening'

一旦 dgram.Socket 可寻址并且可以接收数据,则会触发 'listening' 事件。这会在 socket.bind() 中显式地发生,或者在第一次使用 socket.send() 发送数据时隐式地发生。直到 dgram.Socket 正在监听,底层系统资源不存在,则调用 socket.address()socket.setTTL() 等将失败。

¥The 'listening' event is emitted once the dgram.Socket is addressable and can receive data. This happens either explicitly with socket.bind() or implicitly the first time data is sent using socket.send(). Until the dgram.Socket is listening, the underlying system resources do not exist and calls such as socket.address() and socket.setTTL() will fail.

事件:'message'#

¥Event: 'message'

当套接字上有新的数据报可用时,则会触发 'message' 事件。事件处理函数传递了两个参数:msgrinfo

¥The 'message' event is emitted when a new datagram is available on a socket. The event handler function is passed two arguments: msg and rinfo.

如果传入数据包的源地址是 IPv6 链路本地地址,则将接口名称添加到 address。例如,在 en0 接口上接收的数据包可能将地址字段设置为 'fe80::2618:1234:ab11:3b9c%en0',其中 '%en0' 是作为区域 ID 后缀的接口名称。

¥If the source address of the incoming packet is an IPv6 link-local address, the interface name is added to the address. For example, a packet received on the en0 interface might have the address field set to 'fe80::2618:1234:ab11:3b9c%en0', where '%en0' is the interface name as a zone ID suffix.

socket.addMembership(multicastAddress[, multicastInterface])#

使用 IP_ADD_MEMBERSHIP 套接字选项告诉内核在给定的 multicastAddressmulticastInterface 上加入多播组。如果未指定 multicastInterface 参数,则操作系统将选择一个接口并为其添加成员资格。要为每个可用接口添加成员资格,则多次调用 addMembership,每个接口一次。

¥Tells the kernel to join a multicast group at the given multicastAddress and multicastInterface using the IP_ADD_MEMBERSHIP socket option. If the multicastInterface argument is not specified, the operating system will choose one interface and will add membership to it. To add membership to every available interface, call addMembership multiple times, once per interface.

当在未绑定的套接字上调用时,则此方法将隐式地绑定到随机端口,监听所有接口。

¥When called on an unbound socket, this method will implicitly bind to a random port, listening on all interfaces.

当在多个 cluster 工作进程共享 UDP 套接字时,则必须只调用一次 socket.addMembership() 函数,否则会发生 EADDRINUSE 错误:

¥When sharing a UDP socket across multiple cluster workers, the socket.addMembership() function must be called only once or an EADDRINUSE error will occur:

import cluster from 'node:cluster';
import dgram from 'node:dgram';

if (cluster.isPrimary) {
  cluster.fork(); // Works ok.
  cluster.fork(); // Fails with EADDRINUSE.
} else {
  const s = dgram.createSocket('udp4');
  s.bind(1234, () => {
    s.addMembership('224.0.0.114');
  });
}const cluster = require('node:cluster');
const dgram = require('node:dgram');

if (cluster.isPrimary) {
  cluster.fork(); // Works ok.
  cluster.fork(); // Fails with EADDRINUSE.
} else {
  const s = dgram.createSocket('udp4');
  s.bind(1234, () => {
    s.addMembership('224.0.0.114');
  });
}

socket.addSourceSpecificMembership(sourceAddress, groupAddress[, multicastInterface])#

告诉内核在给定的 sourceAddressgroupAddress 上加入特定于源的多播通道,使用 multicastInterfaceIP_ADD_SOURCE_MEMBERSHIP 套接字选项。如果未指定 multicastInterface 参数,则操作系统将选择一个接口并为其添加成员资格。要为每个可用接口添加成员资格,则多次调用 socket.addSourceSpecificMembership(),每个接口一次。

¥Tells the kernel to join a source-specific multicast channel at the given sourceAddress and groupAddress, using the multicastInterface with the IP_ADD_SOURCE_MEMBERSHIP socket option. If the multicastInterface argument is not specified, the operating system will choose one interface and will add membership to it. To add membership to every available interface, call socket.addSourceSpecificMembership() multiple times, once per interface.

当在未绑定的套接字上调用时,则此方法将隐式地绑定到随机端口,监听所有接口。

¥When called on an unbound socket, this method will implicitly bind to a random port, listening on all interfaces.

socket.address()#

返回包含套接字地址信息的对象。对于 UDP 套接字,此对象将包含 addressfamilyport 属性。

¥Returns an object containing the address information for a socket. For UDP sockets, this object will contain address, family, and port properties.

如果在未绑定的套接字上调用此方法将抛出 EBADF

¥This method throws EBADF if called on an unbound socket.

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

对于 UDP 套接字,使 dgram.Socket 在命名的 port 和可选的 address 上监听数据报消息。如果未指定 port0,则操作系统将尝试绑定到随机端口。如果未指定 address,则操作系统将尝试监听所有地址。一旦绑定完成,则会触发 'listening' 事件并调用可选的 callback 函数。

¥For UDP sockets, causes the dgram.Socket to listen for datagram messages on a named port and optional address. If port is not specified or is 0, the operating system will attempt to bind to a random port. If address is not specified, the operating system will attempt to listen on all addresses. Once binding is complete, a 'listening' event is emitted and the optional callback function is called.

同时指定 'listening' 事件监听器并将 callback 传给 socket.bind() 方法无害但不是很有用。

¥Specifying both a 'listening' event listener and passing a callback to the socket.bind() method is not harmful but not very useful.

绑定的数据报套接字使 Node.js 进程保持运行以接收数据报消息。

¥A bound datagram socket keeps the Node.js process running to receive datagram messages.

如果绑定失败,则生成 'error' 事件。在极少数情况下(例如,尝试与关闭的套接字绑定),可能会抛出 Error

¥If binding fails, an 'error' event is generated. In rare case (e.g. attempting to bind with a closed socket), an Error may be thrown.

UDP 服务器监听端口 41234 的示例:

¥Example of a UDP server listening on port 41234:

import dgram from 'node:dgram';

const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.error(`server error:\n${err.stack}`);
  server.close();
});

server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

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

server.bind(41234);
// Prints: server listening 0.0.0.0:41234const dgram = require('node:dgram');
const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.error(`server error:\n${err.stack}`);
  server.close();
});

server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

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

server.bind(41234);
// Prints: server listening 0.0.0.0:41234

socket.bind(options[, callback])#

对于 UDP 套接字,使 dgram.Socket 监听命名 port 和可选 address 上的数据报消息,这些消息作为作为第一个参数传入的 options 对象的属性传入。如果未指定 port0,则操作系统将尝试绑定到随机端口。如果未指定 address,则操作系统将尝试监听所有地址。一旦绑定完成,则会触发 'listening' 事件并调用可选的 callback 函数。

¥For UDP sockets, causes the dgram.Socket to listen for datagram messages on a named port and optional address that are passed as properties of an options object passed as the first argument. If port is not specified or is 0, the operating system will attempt to bind to a random port. If address is not specified, the operating system will attempt to listen on all addresses. Once binding is complete, a 'listening' event is emitted and the optional callback function is called.

options 对象可能包含 fd 属性。当设置了大于 0fd 时,则将使用给定的文件描述符环绕现有的套接字。在这种情况下,portaddress 的属性将被忽略。

¥The options object may contain a fd property. When a fd greater than 0 is set, it will wrap around an existing socket with the given file descriptor. In this case, the properties of port and address will be ignored.

同时指定 'listening' 事件监听器并将 callback 传给 socket.bind() 方法无害但不是很有用。

¥Specifying both a 'listening' event listener and passing a callback to the socket.bind() method is not harmful but not very useful.

options 对象可能包含额外的 exclusive 属性,当将 dgram.Socket 对象与 cluster 模块一起使用时会使用该属性。当 exclusive 设置为 false(默认)时,集群工作进程将使用相同的底层套接字句柄,允许共享连接处理职责。但是,当 exclusivetrue 时,则句柄未共享,尝试共享端口会导致错误。

¥The options object may contain an additional exclusive property that is used when using dgram.Socket objects with the cluster module. When exclusive is set to false (the default), cluster workers will use the same underlying socket handle allowing connection handling duties to be shared. When exclusive is true, however, the handle is not shared and attempted port sharing results in an error.

绑定的数据报套接字使 Node.js 进程保持运行以接收数据报消息。

¥A bound datagram socket keeps the Node.js process running to receive datagram messages.

如果绑定失败,则生成 'error' 事件。在极少数情况下(例如,尝试与关闭的套接字绑定),可能会抛出 Error

¥If binding fails, an 'error' event is generated. In rare case (e.g. attempting to bind with a closed socket), an Error may be thrown.

监听独占端口的套接字示例如下所示。

¥An example socket listening on an exclusive port is shown below.

socket.bind({
  address: 'localhost',
  port: 8000,
  exclusive: true,
}); 

socket.close([callback])#

  • callback <Function> 当套接字关闭时调用。

    ¥callback <Function> Called when the socket has been closed.

关闭底层套接字并停止监听其上的数据。如果提供回调,则将其添加为 'close' 事件的监听器。

¥Close the underlying socket and stop listening for data on it. If a callback is provided, it is added as a listener for the 'close' event.

socket[Symbol.asyncDispose]()#

稳定性: 1 - 实验性的

¥Stability: 1 - Experimental

调用 socket.close() 并返回一个在套接字关闭时履行的 promise。

¥Calls socket.close() and returns a promise that fulfills when the socket has closed.

socket.connect(port[, address][, callback])#

dgram.Socket 关联到远程地址和端口。此句柄发送的每条消息都会自动发送到该目标。此外,套接字将只接收来自该远程对等方的消息。尝试在已连接的套接字上调用 connect() 将导致 ERR_SOCKET_DGRAM_IS_CONNECTED 异常。如果未提供 address,则默认使用 '127.0.0.1'(适用于 udp4 套接字)或 '::1'(适用于 udp6 套接字)。一旦连接完成,就会触发 'connect' 事件并调用可选的 callback 函数。如果失败,则调用 callback,或者触发 'error' 事件。

¥Associates the dgram.Socket to a remote address and port. Every message sent by this handle is automatically sent to that destination. Also, the socket will only receive messages from that remote peer. Trying to call connect() on an already connected socket will result in an ERR_SOCKET_DGRAM_IS_CONNECTED exception. If address is not provided, '127.0.0.1' (for udp4 sockets) or '::1' (for udp6 sockets) will be used by default. Once the connection is complete, a 'connect' event is emitted and the optional callback function is called. In case of failure, the callback is called or, failing this, an 'error' event is emitted.

socket.disconnect()#

将连接的 dgram.Socket 与其远程地址分离的同步函数。尝试在未绑定或已断开连接的套接字上调用 disconnect() 将导致 ERR_SOCKET_DGRAM_NOT_CONNECTED 异常。

¥A synchronous function that disassociates a connected dgram.Socket from its remote address. Trying to call disconnect() on an unbound or already disconnected socket will result in an ERR_SOCKET_DGRAM_NOT_CONNECTED exception.

socket.dropMembership(multicastAddress[, multicastInterface])#

指示内核使用 IP_DROP_MEMBERSHIP 套接字选项离开 multicastAddress 处的多播组。当套接字关闭或进程终止时,内核会自动调用此方法,因此大多数应用永远没有理由调用此方法。

¥Instructs the kernel to leave a multicast group at multicastAddress using the IP_DROP_MEMBERSHIP socket option. This method is automatically called by the kernel when the socket is closed or the process terminates, so most apps will never have reason to call this.

如果未指定 multicastInterface,则操作系统将尝试删除所有有效接口上的成员资格。

¥If multicastInterface is not specified, the operating system will attempt to drop membership on all valid interfaces.

socket.dropSourceSpecificMembership(sourceAddress, groupAddress[, multicastInterface])#

指示内核使用 IP_DROP_SOURCE_MEMBERSHIP 套接字选项在给定的 sourceAddressgroupAddress 处保留特定于源的多播通道。当套接字关闭或进程终止时,内核会自动调用此方法,因此大多数应用永远没有理由调用此方法。

¥Instructs the kernel to leave a source-specific multicast channel at the given sourceAddress and groupAddress using the IP_DROP_SOURCE_MEMBERSHIP socket option. This method is automatically called by the kernel when the socket is closed or the process terminates, so most apps will never have reason to call this.

如果未指定 multicastInterface,则操作系统将尝试删除所有有效接口上的成员资格。

¥If multicastInterface is not specified, the operating system will attempt to drop membership on all valid interfaces.

socket.getRecvBufferSize()#

  • 返回:<number> SO_RCVBUF 套接字接收缓冲区大小(以字节为单位)。

    ¥Returns: <number> the SO_RCVBUF socket receive buffer size in bytes.

如果在未绑定的套接字上调用此方法将抛出 ERR_SOCKET_BUFFER_SIZE

¥This method throws ERR_SOCKET_BUFFER_SIZE if called on an unbound socket.

socket.getSendBufferSize()#

  • 返回:<number> SO_SNDBUF 套接字发送缓冲区大小(以字节为单位)。

    ¥Returns: <number> the SO_SNDBUF socket send buffer size in bytes.

如果在未绑定的套接字上调用此方法将抛出 ERR_SOCKET_BUFFER_SIZE

¥This method throws ERR_SOCKET_BUFFER_SIZE if called on an unbound socket.

socket.getSendQueueSize()#

  • 返回:<number> 排队等待发送的字节数。

    ¥Returns: <number> Number of bytes queued for sending.

socket.getSendQueueCount()#

  • 返回:<number> 当前队列中等待处理的发送请求数。

    ¥Returns: <number> Number of send requests currently in the queue awaiting to be processed.

socket.ref()#

默认情况下,只要套接字处于打开状态,则绑定套接字将导致它阻止 Node.js 进程退出。socket.unref() 方法可用于从保持 Node.js 进程处于活动状态的引用计数中排除套接字。socket.ref() 方法将套接字添加回引用计数并恢复默认行为。

¥By default, binding a socket will cause it to block the Node.js process from exiting as long as the socket is open. The socket.unref() method can be used to exclude the socket from the reference counting that keeps the Node.js process active. The socket.ref() method adds the socket back to the reference counting and restores the default behavior.

多次调用 socket.ref() 不会有额外的效果。

¥Calling socket.ref() multiples times will have no additional effect.

socket.ref() 方法返回对套接字的引用,因此可以链接调用。

¥The socket.ref() method returns a reference to the socket so calls can be chained.

socket.remoteAddress()#

返回包含远程端点的 addressfamilyport 的对象。如果套接字未连接,则此方法将抛出 ERR_SOCKET_DGRAM_NOT_CONNECTED 异常。

¥Returns an object containing the address, family, and port of the remote endpoint. This method throws an ERR_SOCKET_DGRAM_NOT_CONNECTED exception if the socket is not connected.

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

在套接字上广播数据报。对于无连接套接字,则必须指定目标 portaddress。另一方面,已连接的套接字将使用其关联的远程端点,因此不得设置 portaddress 参数。

¥Broadcasts a datagram on the socket. For connectionless sockets, the destination port and address must be specified. Connected sockets, on the other hand, will use their associated remote endpoint, so the port and address arguments must not be set.

msg 参数包含要发送的消息。根据其类型,可以应用不同的行为。如果 msgBuffer、任何 TypedArrayDataView,则 offsetlength 分别指定消息开始的 Buffer 中的偏移量和消息中的字节数。如果 msgString,则会自动转换为 'utf8' 编码的 Buffer。对于包含多字节字符的消息,offsetlength 将根据 字节长度 而不是字符位置进行计算。如果 msg 是数组,则不能指定 offsetlength

¥The msg argument contains the message to be sent. Depending on its type, different behavior can apply. If msg is a Buffer, any TypedArray or a DataView, the offset and length specify the offset within the Buffer where the message begins and the number of bytes in the message, respectively. If msg is a String, then it is automatically converted to a Buffer with 'utf8' encoding. With messages that contain multi-byte characters, offset and length will be calculated with respect to byte length and not the character position. If msg is an array, offset and length must not be specified.

address 参数是字符串。如果 address 的值是主机名,则会使用 DNS 解析主机地址。如果未提供 address 或以其他方式无效,则默认使用 '127.0.0.1'(用于 udp4 套接字)或 '::1'(用于 udp6 套接字)。

¥The address argument is a string. If the value of address is a host name, DNS will be used to resolve the address of the host. If address is not provided or otherwise nullish, '127.0.0.1' (for udp4 sockets) or '::1' (for udp6 sockets) will be used by default.

如果套接字之前没有绑定过对 bind 的调用,则套接字会分配一个随机端口号并绑定到 "所有接口" 地址('0.0.0.0' 用于 udp4 套接字,'::0' 用于 udp6 套接字。)

¥If the socket has not been previously bound with a call to bind, the socket is assigned a random port number and is bound to the "all interfaces" address ('0.0.0.0' for udp4 sockets, '::0' for udp6 sockets.)

可以指定可选的 callback 函数作为报告 DNS 错误或确定何时可以安全地重用 buf 对象的一种方式。DNS 查找延迟了 Node.js 事件循环的至少一滴答的发送时间。

¥An optional callback function may be specified to as a way of reporting DNS errors or for determining when it is safe to reuse the buf object. DNS lookups delay the time to send for at least one tick of the Node.js event loop.

确定数据报已发送的唯一方法是使用 callback。如果发生错误并给出 callback,则错误将作为第一个参数传给 callback。如果未给出 callback,则错误将作为 socket 对象上的 'error' 事件触发。

¥The only way to know for sure that the datagram has been sent is by using a callback. If an error occurs and a callback is given, the error will be passed as the first argument to the callback. If a callback is not given, the error is emitted as an 'error' event on the socket object.

偏移量和长度是可选的,但如果使用其中一个,则必须设置两者。仅当第一个参数是 BufferTypedArrayDataView 时才支持它们。

¥Offset and length are optional but both must be set if either are used. They are supported only when the first argument is a Buffer, a TypedArray, or a DataView.

如果在未绑定的套接字上调用此方法将抛出 ERR_SOCKET_BAD_PORT

¥This method throws ERR_SOCKET_BAD_PORT if called on an unbound socket.

发送 UDP 包到 localhost 端口的示例;

¥Example of sending a UDP packet to a port on localhost;

import dgram from 'node:dgram';
import { Buffer } from 'node:buffer';

const message = Buffer.from('Some bytes');
const client = dgram.createSocket('udp4');
client.send(message, 41234, 'localhost', (err) => {
  client.close();
});const dgram = require('node:dgram');
const { Buffer } = require('node:buffer');

const message = Buffer.from('Some bytes');
const client = dgram.createSocket('udp4');
client.send(message, 41234, 'localhost', (err) => {
  client.close();
});

发送由多个缓冲区组成的 UDP 数据包到 127.0.0.1 上的端口的示例;

¥Example of sending a UDP packet composed of multiple buffers to a port on 127.0.0.1;

import dgram from 'node:dgram';
import { Buffer } from 'node:buffer';

const buf1 = Buffer.from('Some ');
const buf2 = Buffer.from('bytes');
const client = dgram.createSocket('udp4');
client.send([buf1, buf2], 41234, (err) => {
  client.close();
});const dgram = require('node:dgram');
const { Buffer } = require('node:buffer');

const buf1 = Buffer.from('Some ');
const buf2 = Buffer.from('bytes');
const client = dgram.createSocket('udp4');
client.send([buf1, buf2], 41234, (err) => {
  client.close();
});

发送多个缓冲区可能更快或更慢,这取决于应用和操作系统。运行基准测试以根据具体情况确定最佳策略。但是,一般来说,发送多个缓冲区会更快。

¥Sending multiple buffers might be faster or slower depending on the application and operating system. Run benchmarks to determine the optimal strategy on a case-by-case basis. Generally speaking, however, sending multiple buffers is faster.

使用连接到 localhost 端口的套接字发送 UDP 数据包的示例:

¥Example of sending a UDP packet using a socket connected to a port on localhost:

import dgram from 'node:dgram';
import { Buffer } from 'node:buffer';

const message = Buffer.from('Some bytes');
const client = dgram.createSocket('udp4');
client.connect(41234, 'localhost', (err) => {
  client.send(message, (err) => {
    client.close();
  });
});const dgram = require('node:dgram');
const { Buffer } = require('node:buffer');

const message = Buffer.from('Some bytes');
const client = dgram.createSocket('udp4');
client.connect(41234, 'localhost', (err) => {
  client.send(message, (err) => {
    client.close();
  });
});

关于 UDP 数据报大小的注意事项#

¥Note about UDP datagram size

IPv4/v6 数据报的最大大小取决于 MTU(最大传输单元)和 Payload Length 字段大小。

¥The maximum size of an IPv4/v6 datagram depends on the MTU (Maximum Transmission Unit) and on the Payload Length field size.

  • Payload Length 字段为 16 位宽,这意味着正常负载不能超过 64K 八位位组,包括互联网标头和数据(65,507 字节 = 65,535 − 8 字节 UDP 标头 − 20 字节 IP 标头);这通常适用于环回接口,但对于大多数主机和网络来说,如此长的数据报消息是不切实际的。

    ¥The Payload Length field is 16 bits wide, which means that a normal payload cannot exceed 64K octets including the internet header and data (65,507 bytes = 65,535 − 8 bytes UDP header − 20 bytes IP header); this is generally true for loopback interfaces, but such long datagram messages are impractical for most hosts and networks.

  • MTU 是给定链路层技术可以支持数据报消息的最大尺寸。对于任何链接,IPv4 要求至少 MTU 为 68 个八位字节,而建议 IPv4 的 MTU 为 576(通常建议为拨号类型应用的 MTU),无论它们是完整的还是分段的。

    ¥The MTU is the largest size a given link layer technology can support for datagram messages. For any link, IPv4 mandates a minimum MTU of 68 octets, while the recommended MTU for IPv4 is 576 (typically recommended as the MTU for dial-up type applications), whether they arrive whole or in fragments.

    对于 IPv6,最小 MTU 是 1280 个八位字节。但是,强制的最小片段重组缓冲区大小是 1500 个八位字节。68 个八位字节的值非常小,因为大多数当前的链路层技术,如以太网,最小 MTU 为 1500。

    ¥For IPv6, the minimum MTU is 1280 octets. However, the mandatory minimum fragment reassembly buffer size is 1500 octets. The value of 68 octets is very small, since most current link layer technologies, like Ethernet, have a minimum MTU of 1500.

不可能事先知道数据包可能通过的每个链路的 MTU。发送大于接收方 MTU 的数据报将不起作用,因为数据包将被悄悄丢弃,而不会通知源数据未到达其预期接收方。

¥It is impossible to know in advance the MTU of each link through which a packet might travel. Sending a datagram greater than the receiver MTU will not work because the packet will get silently dropped without informing the source that the data did not reach its intended recipient.

socket.setBroadcast(flag)#

设置或清除 SO_BROADCAST 套接字选项。当设置为 true 时,UDP 数据包可能会被发送到本地接口的广播地址。

¥Sets or clears the SO_BROADCAST socket option. When set to true, UDP packets may be sent to a local interface's broadcast address.

如果在未绑定的套接字上调用此方法将抛出 EBADF

¥This method throws EBADF if called on an unbound socket.

socket.setMulticastInterface(multicastInterface)#

本节中所有对范围的引用均指 IPv6 区域索引,由 RFC 4007 定义。在字符串形式中,具有范围索引的 IP 写为 'IP%scope',其中范围是接口名称或接口编号。

¥All references to scope in this section are referring to IPv6 Zone Indices, which are defined by RFC 4007. In string form, an IP with a scope index is written as 'IP%scope' where scope is an interface name or interface number.

将套接字的默认传出多播接口设置为选定接口或返回系统接口选择。multicastInterface 必须是来自套接字家族的 IP 的有效字符串表示形式。

¥Sets the default outgoing multicast interface of the socket to a chosen interface or back to system interface selection. The multicastInterface must be a valid string representation of an IP from the socket's family.

对于 IPv4 套接字,这应该是为所需物理接口配置的 IP。在套接字上发送到多播的所有数据包都将在最近成功使用此调用确定的接口上发送。

¥For IPv4 sockets, this should be the IP configured for the desired physical interface. All packets sent to multicast on the socket will be sent on the interface determined by the most recent successful use of this call.

对于 IPv6 套接字,multicastInterface 应包括范围来指示接口,如以下示例中所示。在 IPv6 中,单个 send 调用也可以在地址中使用显式范围,因此只有发送到多播地址而未指定显式范围的数据包才会受到最近成功使用此调用的影响。

¥For IPv6 sockets, multicastInterface should include a scope to indicate the interface as in the examples that follow. In IPv6, individual send calls can also use explicit scope in addresses, so only packets sent to a multicast address without specifying an explicit scope are affected by the most recent successful use of this call.

如果在未绑定的套接字上调用此方法将抛出 EBADF

¥This method throws EBADF if called on an unbound socket.

示例:IPv6 输出组播接口#

¥Example: IPv6 outgoing multicast interface

在大多数系统上,范围格式使用接口名称:

¥On most systems, where scope format uses the interface name:

const socket = dgram.createSocket('udp6');

socket.bind(1234, () => {
  socket.setMulticastInterface('::%eth1');
}); 

在 Windows 上,范围格式使用接口编号:

¥On Windows, where scope format uses an interface number:

const socket = dgram.createSocket('udp6');

socket.bind(1234, () => {
  socket.setMulticastInterface('::%2');
}); 

示例:IPv4 输出组播接口#

¥Example: IPv4 outgoing multicast interface

所有系统都在所需的物理接口上使用主机的 IP:

¥All systems use an IP of the host on the desired physical interface:

const socket = dgram.createSocket('udp4');

socket.bind(1234, () => {
  socket.setMulticastInterface('10.0.0.2');
}); 

调用结果#

¥Call results

对未准备好发送或不再打开的套接字的调用可能会抛出 Not running Error

¥A call on a socket that is not ready to send or no longer open may throw a Not running Error.

如果无法将 multicastInterface 解析为 IP,则抛出 EINVAL System Error

¥If multicastInterface can not be parsed into an IP then an EINVAL System Error is thrown.

在 IPv4 上,如果 multicastInterface 是有效地址但与任何接口都不匹配,或者如果地址与系列不匹配,则抛出 System Error,例如 EADDRNOTAVAILEPROTONOSUP

¥On IPv4, if multicastInterface is a valid address but does not match any interface, or if the address does not match the family then a System Error such as EADDRNOTAVAIL or EPROTONOSUP is thrown.

在 IPv6 上,大多数指定或省略范围的错误将导致套接字继续使用(或返回)系统的默认接口选择。

¥On IPv6, most errors with specifying or omitting scope will result in the socket continuing to use (or returning to) the system's default interface selection.

套接字地址族的任何地址(IPv4 '0.0.0.0' 或 IPv6 '::')可用于将套接字默认传出接口的控制权返回给系统,以便将来使用多播数据包。

¥A socket's address family's ANY address (IPv4 '0.0.0.0' or IPv6 '::') can be used to return control of the sockets default outgoing interface to the system for future multicast packets.

socket.setMulticastLoopback(flag)#

设置或清除 IP_MULTICAST_LOOP 套接字选项。当设置为 true 时,本地接口也会收到多播数据包。

¥Sets or clears the IP_MULTICAST_LOOP socket option. When set to true, multicast packets will also be received on the local interface.

如果在未绑定的套接字上调用此方法将抛出 EBADF

¥This method throws EBADF if called on an unbound socket.

socket.setMulticastTTL(ttl)#

设置 IP_MULTICAST_TTL 套接字选项。虽然 TTL 通常代表 "生存时间",但在此上下文中,它指定了允许数据包通过的 IP 跃点数,特别是对于多播流量。转发数据包的每个路由或网关都会递减 TTL。如果 TTL 被路由递减为 0,则不会转发。

¥Sets the IP_MULTICAST_TTL socket option. While TTL generally stands for "Time to Live", in this context it specifies the number of IP hops that a packet is allowed to travel through, specifically for multicast traffic. Each router or gateway that forwards a packet decrements the TTL. If the TTL is decremented to 0 by a router, it will not be forwarded.

ttl 参数可以是 0 到 255 之间。大多数系统上的默认值为 1

¥The ttl argument may be between 0 and 255. The default on most systems is 1.

如果在未绑定的套接字上调用此方法将抛出 EBADF

¥This method throws EBADF if called on an unbound socket.

socket.setRecvBufferSize(size)#

设置 SO_RCVBUF 套接字选项。设置最大套接字接收缓冲区(以字节为单位)。

¥Sets the SO_RCVBUF socket option. Sets the maximum socket receive buffer in bytes.

如果在未绑定的套接字上调用此方法将抛出 ERR_SOCKET_BUFFER_SIZE

¥This method throws ERR_SOCKET_BUFFER_SIZE if called on an unbound socket.

socket.setSendBufferSize(size)#

设置 SO_SNDBUF 套接字选项。设置最大套接字发送缓冲区(以字节为单位)。

¥Sets the SO_SNDBUF socket option. Sets the maximum socket send buffer in bytes.

如果在未绑定的套接字上调用此方法将抛出 ERR_SOCKET_BUFFER_SIZE

¥This method throws ERR_SOCKET_BUFFER_SIZE if called on an unbound socket.

socket.setTTL(ttl)#

设置 IP_TTL 套接字选项。虽然 TTL 通常代表 "生存时间",但在此上下文中,它指定了允许数据包通过的 IP 跃点数。转发数据包的每个路由或网关都会递减 TTL。如果 TTL 被路由递减为 0,则不会转发。更改 TTL 值通常用于网络探测或多播。

¥Sets the IP_TTL socket option. While TTL generally stands for "Time to Live", in this context it specifies the number of IP hops that a packet is allowed to travel through. Each router or gateway that forwards a packet decrements the TTL. If the TTL is decremented to 0 by a router, it will not be forwarded. Changing TTL values is typically done for network probes or when multicasting.

ttl 参数可能在 1 到 255 之间。大多数系统的默认值为 64。

¥The ttl argument may be between 1 and 255. The default on most systems is 64.

如果在未绑定的套接字上调用此方法将抛出 EBADF

¥This method throws EBADF if called on an unbound socket.

socket.unref()#

默认情况下,只要套接字处于打开状态,则绑定套接字将导致它阻止 Node.js 进程退出。socket.unref() 方法可用于将套接字从保持 Node.js 进程处于活动状态的引用计数中排除,即使套接字仍在监听,也允许进程退出。

¥By default, binding a socket will cause it to block the Node.js process from exiting as long as the socket is open. The socket.unref() method can be used to exclude the socket from the reference counting that keeps the Node.js process active, allowing the process to exit even if the socket is still listening.

多次调用 socket.unref() 不会有额外的效果。

¥Calling socket.unref() multiple times will have no additional effect.

socket.unref() 方法返回对套接字的引用,因此可以链接调用。

¥The socket.unref() method returns a reference to the socket so calls can be chained.

node:dgram 模块函数#

¥node:dgram module functions

dgram.createSocket(options[, callback])#

  • options <Object> 可用的选项有:

    ¥options <Object> Available options are:

    • type <string> 套接字家族。必须是 'udp4''udp6'。必需的。

      ¥type <string> The family of socket. Must be either 'udp4' or 'udp6'. Required.

    • reuseAddr <boolean>true socket.bind() 将重用该地址时,即使另一个进程已经在其上绑定了套接字。默认值:false

      ¥reuseAddr <boolean> When true socket.bind() will reuse the address, even if another process has already bound a socket on it. Default: false.

    • ipv6Only <boolean>ipv6Only 设置为 true 将禁用双栈支持,即绑定到地址 :: 不会使 0.0.0.0 被绑定。默认值:false

      ¥ipv6Only <boolean> Setting ipv6Only to true will disable dual-stack support, i.e., binding to address :: won't make 0.0.0.0 be bound. Default: false.

    • recvBufferSize <number> 设置 SO_RCVBUF 套接字值。

      ¥recvBufferSize <number> Sets the SO_RCVBUF socket value.

    • sendBufferSize <number> 设置 SO_SNDBUF 套接字值。

      ¥sendBufferSize <number> Sets the SO_SNDBUF socket value.

    • lookup <Function> 自定义查找函数。默认值:dns.lookup()

      ¥lookup <Function> Custom lookup function. Default: dns.lookup().

    • signal <AbortSignal> 可用于关闭套接字的中止信号。

      ¥signal <AbortSignal> An AbortSignal that may be used to close a socket.

  • callback <Function> 绑定作为 'message' 事件的监听器。可选的。

    ¥callback <Function> Attached as a listener for 'message' events. Optional.

  • 返回:<dgram.Socket>

    ¥Returns: <dgram.Socket>

创建 dgram.Socket 对象。一旦创建了套接字,则调用 socket.bind() 将指示套接字开始监听数据报消息。当 addressport 未传递给 socket.bind() 时,该方法会将套接字绑定到随机端口上的 "所有接口" 地址(它对 udp4udp6 套接字都做正确的事情)。可以使用 socket.address().addresssocket.address().port 检索绑定的地址和端口。

¥Creates a dgram.Socket object. Once the socket is created, calling socket.bind() will instruct the socket to begin listening for datagram messages. When address and port are not passed to socket.bind() the method will bind the socket to the "all interfaces" address on a random port (it does the right thing for both udp4 and udp6 sockets). The bound address and port can be retrieved using socket.address().address and socket.address().port.

如果启用了 signal 选项,则在对应的 AbortController 上调用 .abort() 与在套接字上调用 .close() 类似:

¥If the signal option is enabled, calling .abort() on the corresponding AbortController is similar to calling .close() on the socket:

const controller = new AbortController();
const { signal } = controller;
const server = dgram.createSocket({ type: 'udp4', signal });
server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});
// Later, when you want to close the server.
controller.abort(); 

dgram.createSocket(type[, callback])#

创建指定 typedgram.Socket 对象。

¥Creates a dgram.Socket object of the specified type.

一旦创建了套接字,则调用 socket.bind() 将指示套接字开始监听数据报消息。当 addressport 未传递给 socket.bind() 时,该方法会将套接字绑定到随机端口上的 "所有接口" 地址(它对 udp4udp6 套接字都做正确的事情)。可以使用 socket.address().addresssocket.address().port 检索绑定的地址和端口。

¥Once the socket is created, calling socket.bind() will instruct the socket to begin listening for datagram messages. When address and port are not passed to socket.bind() the method will bind the socket to the "all interfaces" address on a random port (it does the right thing for both udp4 and udp6 sockets). The bound address and port can be retrieved using socket.address().address and socket.address().port.