Node.js v10.16.3 文档


目录

net(网络)#

中英对照提交修改

稳定性: 2 - 稳定

net 模块用于创建基于流的 TCP 或 IPC 的服务器(net.createServer())与客户端(net.createConnection())。

使用方法如下:

const net = require('net');

IPC 支持#

中英对照提交修改

net 模块在 Windows 上支持命名管道 IPC,在其他操作系统上支持 Unix 域套接字。

IPC 连接的识别路径#

中英对照提交修改

net.connect(), net.createConnection(), server.listen()socket.connect() 使用一个 path 参数来识别 IPC 端点。

在 Unix 上,本地域也称为 Unix 域。 参数 path 是文件系统路径名。 它被从 sizeof(sockaddr_un.sun_path) - 1 处被截断,其长度因操作系统不同而在 91 至 107 字节之间变化。 典型值在 Linux 上为 107,在 macOS 上为 103。 该路径受到与创建文件相同的命名约定和权限检查。 如果创建 Unix 域套接字(作为文件系统路径可见)并与 Node.js 的 API 抽象之一(例如 net.createServer())一起使用,则它将作为 server.close() 的一部分取消链接。 另一方面,如果在这些抽象之外创建和使用它,则用户需要手动删除它。 当路径由 Node.js API 创建但程序突然崩溃时,同样适用。 简而言之,一旦成功创建的 Unix 域套接字将在文件系统中可见,并将持续到取消链接。

在 Windows 上,本地域通过命名管道实现。路径必须是以 \\?\pipe\\\.\pipe\ 为入口。路径允许任何字符,但后面的字符可能会对管道名称进行一些处理,例如解析 .. 序列。尽管如此,管道空间是平面的。管道不会持续,当最后一次引用关闭时,管道就会被删除。

JavaScript 字符串转义需要使用双反斜杠指定路径,例如:

net.createServer().listen(
  path.join('\\\\?\\pipe', process.cwd(), 'myctl'));

net.Server 类#

中英对照提交修改

这个类用于创建 TCP 或 IPC server。

new net.Server([options][, connectionlistener])#

中英对照提交修改

net.Server 是一个 EventEmitter,实现了以下事件:

'close' 事件#

中英对照提交修改

当 server 关闭的时候触发。 如果有连接存在,直到所有的连接结束才会触发这个事件。

'connection' 事件#

中英对照提交修改

当一个新的连接建立的时候触发。 socket 是一个 net.Socket 实例。

'error' 事件#

中英对照提交修改

当错误出现的时候触发。 不同于 net.Socket'close' 事件不会在这个事件触发后继续触发,除非 server.close() 是手动调用。 参阅 server.listen() 中的例子。

'listening' 事件#

中英对照提交修改

当调用 server.listen() 绑定服务器之后触发。

server.address()#

中英对照提交修改

如果在 IP socket 上监听,则返回操作系统报告的绑定的 address、地址 family 名称、以及服务器 port(用于查找在获取操作系统分配的地址时分配的端口):{ port: 12346, family: 'IPv4', address: '127.0.0.1' }

对于在管道或 Unix 域套接字上监听的 server,该名称将返回为字符串。

const server = net.createServer((socket) => {
  socket.end('再见\n');
}).on('error', (err) => {
  // 处理错误
  throw err;
});

// 获取任意未使用的端口。
server.listen(() => {
  console.log('打开服务器', server.address());
});

不要在 'listening' 事件触发之前调用 server.address()

server.close([callback])#

中英对照提交修改

阻止 server 接受新的连接并保持现有的连接。 该函数是异步的,server 将在所有连接结束后关闭并触发 'close' 事件。 可选的 callback 将在 'close' 事件发生时被调用。 与 'close' 事件不同的是,如果 server 在关闭时未打开,回调函数被调用时会传入一个 Error 对象作为唯一参数。

server.connections#

暂无中英对照

稳定性: 0 - 废弃: 改为使用 server.getConnections()

The number of concurrent connections on the server.

This becomes null when sending a socket to a child with child_process.fork(). To poll forks and get current number of active connections, use asynchronous server.getConnections() instead.

server.getConnections(callback)#

中英对照提交修改

异步获取服务器的当前并发连接数。当 socket 被传递给子进程时工作。

回调函数的两个参数是 errcount

server.listen()#

中英对照提交修改

启动一个服务器来监听连接。 net.Server 可以是 TCP 或 IPC 服务器,具体取决于它监听的内容。

可能的参数:

这个函数是异步的。当服务器开始监听时,会触发 'listening' 事件。 最后一个参数 callback 将被添加为 'listening' 事件的监听器。

所有的 listen() 方法都可以使用一个 backlog 参数来指定待连接队列的最大长度。 实际的长度将由操作系统的 sysctl 设置决定,例如 Linux 上的 tcp_max_syn_backlogsomaxconn。 此参数的默认值是 511 (不是512)。

所有的 net.Socket 都被设置为 SO_REUSEADDR (详见 socket(7))。

当且仅当上次调用 server.listen() 发生错误或已经调用 server.close() 时,才能再次调用 server.listen() 方法。否则将抛出 ERR_SERVER_ALREADY_LISTEN 错误。

监听时最常见的错误之一是 EADDRINUSE。 这是因为另一个服务器已正在监听请求的 port/path/handle。 处理此问题的一种方法是在一段时间后重试:

server.on('error', (e) => {
  if (e.code === 'EADDRINUSE') {
    console.log('地址正被使用,重试中...');
    setTimeout(() => {
      server.close();
      server.listen(PORT, HOST);
    }, 1000);
  }
});

server.listen(handle[, backlog][, callback])#

中英对照提交修改

启动一个服务器,监听已经绑定到端口、Unix 域套接字或 Windows 命名管道的给定 handle 上的连接。

handle 对象可以是服务器、套接字(任何具有底层 _handle 成员的东西),也可以是具有 fd 成员的对象,该成员是一个有效的文件描述符。

在 Windows 上不支持在文件描述符上进行监听。

server.listen(options[, callback])#

中英对照提交修改

如果指定了 port 参数,该方法的行为跟 server.listen([port[, host[, backlog]]][, callback]) 一样。 否则,如果指定了 path 参数,该方法的行为与 server.listen(path[, backlog][, callback]) 一致。 如果没有 port 或者 path 参数,则会抛出一个错误。

如果 exclusivefalse(默认),则集群的所有进程将使用相同的底层句柄,允许共享连接处理任务。如果 exclusivetrue,则句柄不会被共享,如果尝试端口共享将导致错误。监听独立端口的例子如下。

server.listen({
  host: 'localhost',
  port: 80,
  exclusive: true
});

以 root 身份启动 IPC 服务器可能导致无特权用户无法访问服务器路径。 使用 readableAllwritableAll 将使所有用户都可以访问服务器。

server.listen(path[, backlog][, callback])#

中英对照提交修改

启动一个 IPC 服务器监听给定 path 的连接。

server.listen([port[, host[, backlog]]][, callback])#

中英对照提交修改

启动一个 TCP 服务监听输入的 porthost

如果 port 省略或是 0,系统会随意分配一个在 'listening' 事件触发后能被 server.address().port 检索的无用端口。

如果 host 省略,如果 IPv6 可用,服务器将会接收基于未指定的 IPv6 地址 (::) 的连接,否则接收基于未指定的 IPv4 地址 (0.0.0.0) 的连接。

在大多数的系统, 监听未指定的 IPv6 地址 (::) 可能导致 net.Server 也监听未指定的 IPv4 地址 (0.0.0.0)。

server.listening#

中英对照提交修改

  • <boolean> 表明 server 是否正在监听连接。

server.maxConnections#

中英对照提交修改

设置该属性使得当 server 连接数过多时拒绝连接。

一旦将一个 socket 发送给 child_process.fork() 生成的子进程,就不推荐使用该选项。

server.ref()#

中英对照提交修改

unref() 相反,在一个已经调用 unref 的 server 中调用 ref(),如果 server 是仅存的 server,则程序不会退出(默认)。对一个已经调用 ref 的 server 再次调用 ref() 将不会再有效果。

server.unref()#

中英对照提交修改

如果这个 server 在事件系统中是唯一有效的,那么对 server 调用 unref() 将允许程序退出。 如果这个 server 已经调用过 unref 那么再次调用 unref() 将不会再有效果。

net.Socket 类#

中英对照提交修改

此类是 TCP 套接字或流式 IPC 端点的抽象(在 Windows 上使用命名管道,否则使用 Unix 域套接字)。 net.Socket 也是双工流,因此它既可读也可写,也是一个 EventEmitter

net.Socket 可以由用户创建并直接用于与服务器交互。 例如,它由 net.createConnection() 返回,因此用户可以使用它与服务器通信。

它也可以由 Node.js 创建,并在收到连接时传给用户。 例如,它被传给 net.Server 上触发的 'connection' 事件的监听器,因此用户可以使用它与客户端进行交互。

new net.Socket([options])#

中英对照提交修改

  • options <Object> 可用选项有

    • fd <number> 如果指定了该参数,则使用一个给定的文件描述符包装一个已存在的 socket,否则将创建一个新的 socket。
    • allowHalfOpen <boolean> 指示是否允许半打开的 TCP 连接。详情查看 net.createServer()'end' 事件。默认值: false
    • readable <boolean> 当传递了 fd 时允许读取 socket,否则忽略。默认值: false
    • writable <boolean> 当传递了 fd 时允许写入 socket,否则忽略。默认值: false
  • 返回: <net.Socket>

创建一个 socket 对象。 新创建的 socket 可以是 TCP socket 也可以是 IPC 端点流,取决于它连接 connect() 到什么。

'close' 事件#

中英对照提交修改

  • had_error <boolean> 如果 socket 有传输错误就为 true。

一旦 socket 完全关闭就发出该事件。参数 had_error 是 boolean 类型,表明 socket 被关闭是否取决于传输错误。

'connect' 事件#

中英对照提交修改

当一个 socket 连接成功建立的时候触发该事件。 查看 net.createConnection()

'data' 事件#

中英对照提交修改

当接收到数据的时触发该事件。data 参数是一个 BufferString。数据编码由 socket.setEncoding() 设置。

Socket 触发 'data' 事件的时候,如果没有监听器则数据将会丢失。

'drain' 事件#

中英对照提交修改

当写入缓冲区变为空时触发。可以用来做上传节流。

也可以查看:socket.write() 的返回值。

'end' 事件#

中英对照提交修改

当 socket 的另一端发送一个 FIN 包的时候触发,从而结束 socket 的可读端。

默认情况下(allowHalfOpenfalse),socket 将发送一个 FIN 数据包,并且一旦写出它的等待写入队列就销毁它的文件描述符。 当然,如果 allowHalfOpen 为 true,socket 就不会自动结束 end() 它的写入端,允许用户写入任意数量的数据。 用户必须调用 end() 显示地结束这个连接(例如发送一个 FIN 数据包)。

'error' 事件#

中英对照提交修改

当错误发生时触发。'close' 事件也会紧接着该事件被触发。

'lookup' 事件#

中英对照提交修改

在找到主机之后创建连接之前触发。不可用于 Unix socket。

'ready' 事件#

中英对照提交修改

套接字准备好使用时触发。

'connect' 后立即触发。

'timeout' 事件#

中英对照提交修改

当 socket 超时的时候触发。该事件只是用来通知 socket 已经闲置。用户必须手动关闭。

也可以查看:socket.setTimeout()

socket.address()#

中英对照提交修改

返回操作系统报告的 socket 的 address、地址的 family 名称、以及 port{ port: 12346, family: 'IPv4', address: '127.0.0.1' }

socket.bufferSize#

中英对照提交修改

net.Socket 具有该属性, socket.write() 工作时需要。它可以帮助用户快速启动和运行。计算机(处理速度)不能总是跟上 socket 的写入速度 - 网络连接可能太慢了。 Node.js 内部将维护一个写入 socket 的数据队列,并在可能的时候将数据发送出去。(内部实现是对 socket 的文件描述符进行轮询其是否是可写状态。)

使用内部缓冲的结果是可能造成内存的增长。此属性显示当前即将被写入的缓冲的字符数。(字符串的数目大致等于即将被写入的字节,但缓冲可能包含字符串,而字符串是惰性编码的,所以实际的字节数是不知道的。)

对处理大量或持续增长的 bufferSize 有经验的用户应该注意使用 socket.pause()socket.resume() 对他们程序中的数据流进行节流。

socket.bytesRead#

中英对照提交修改

接收的字节数量。

socket.bytesWritten#

中英对照提交修改

发送的字节数量。

socket.connect()#

中英对照提交修改

在给定的套接字上启动一个连接。

可能的签名:

该方法是异步的。当连接建立了的时候,'connect' 事件将会被触发。如果连接过程中有问题,'error' 事件将会代替 'connect' 事件被触发,并将错误信息传递给 'error' 监听器。 最后一个参数 connectListener,如果指定了,将会被添加为 'connect' 事件的监听器。

socket.connect(options[, connectListener])#

中英对照提交修改

在给定的 socket 上初始化一个连接。通常该方法是不需要的,应该使用 net.createConnection() 来创建和打开 socket。一般只在实现一个自定义的 Socket 的时候使用该方法。

对于 TCP 连接可能的 options 有:

  • port <number> 必须。Socket 连接的端口。
  • host <string> Socket 连接的主机。默认值: 'localhost'
  • localAddress <string> Socket 连接的本地地址。
  • localPort <number> Socket 连接的本地端口。
  • family <number> IP 栈的版本。 必须为 4600 值表示允许 IPv4 和 IPv6 地址。默认值: 0
  • hints <number> 可选的 dns.lookup() 提示
  • lookup <Function> 自定义的 lookup 方法。默认值: dns.lookup()

对于 IPC 连接可能的 options 有:

socket.connect(path[, connectListener])#

中英对照提交修改

在给定的 socket 上初始化 IPC 连接。

相当使用 { path: path } 作为 options 调用 socket.connect(options[, connectListener]) 方法的别名。

socket.connect(port[, host][, connectlistener])#

中英对照提交修改

在给定的 socket 上初始化一个 TCP 连接。

使用 {port: port, host: host} 作为 options 调用 socket.connect(options[, connectListener]) 方法的别名。

socket.connecting#

中英对照提交修改

如果为 truesocket.connect(options[, connectListener]) 被调用但还未结束。 它将保持为真,直到 socket 连接,然后设置为 false 并触发 'connect' 事件。 注意,socket.connect(options[, connectListener]) 的回调是 'connect' 事件的监听器。

socket.destroy([exception])#

中英对照提交修改

确保在该 socket 上不再有 I/O 活动。仅在出现错误的时候才需要(如解析错误等)。

如果制定了 exception,则将会触发一个 'error' 事件,任何监听器都将接收到 exception 作为一个参数。

socket.destroyed#

中英对照提交修改

  • <boolean> 指示连接是否已经被销毁。一旦连接被销毁就不能再使用它传输任何数据。

socket.end([data][, encoding][, callback])#

中英对照提交修改

半关闭 socket。 例如发送一个 FIN 包。 服务端仍可以发送数据。

如果指定了 data,则相当于调用 socket.write(data, encoding) 之后再调用 socket.end()

socket.localAddress#

中英对照提交修改

远程客户端连接的本地 IP 地址字符串。例如,一个服务端正在连接到 '0.0.0.0',客户端连接到的是 '192.168.1.1',则 socket.localAddress 的值是 '192.168.1.1'

socket.localPort#

中英对照提交修改

用数字表示的本地端口。例如 80 或 21

socket.pause()#

中英对照提交修改

暂停读写数据。也就是说,'data' 事件将不会再被触发。可以用于上传节流。

socket.pending#

中英对照提交修改

如果 socket 尚未连接,则为 true,因为尚未调用 .connect() 或者因为它仍处于连接过程中(参阅 socket.connecting)。

socket.ref()#

中英对照提交修改

unref() 相反,在一个已经调用 unref 的 socket 中调用 ref(),如果 socket 是仅存的 socket,则程序不会退出(默认)。 对一个已经调用 ref 的 socket 再次调用 ref 将不会再有效果。

socket.remoteAddress#

中英对照提交修改

用字符串表示的远程 IP 地址。例如 '74.125.127.100' 或 '2001:4860:a005::68'。如果 socket 被销毁了(如客户端已经失去连接)则其值为 undefined

socket.remoteFamily#

中英对照提交修改

用字符串表示的远程 IP 协议族。'IPv4' 或 'IPv6'

socket.remotePort#

中英对照提交修改

用数字表示的远程端口。例如 80 或 21

socket.resume()#

中英对照提交修改

在调用 socket.pause() 之后恢复读取数据。

socket.setEncoding([encoding])#

中英对照提交修改

设置作为可读流的编码。在 readable.setEncoding() 查看更多详情。

socket.setKeepAlive([enable][, initialdelay])#

中英对照提交修改

启用/禁用长连接功能, 并且在第一个长连接探针被发送到一个空闲的 socket 之前可选则配置初始延迟。

initialDelay(毫秒)用来设置接收到最后一个数据包和发送第一个长连接探针之间的延迟。将 initialDelay 设置为 0,则会保持默认值(或之前设置的值)不变。

socket.setNoDelay([noDelay])#

中英对照提交修改

禁止 Nagle 算法。默认情况下 TCP 连接使用 Nagle 算法,在发送之前缓冲数据。将 noDelay 设置为 true 将会在每次 socket.write() 被调用的时候立即发送数据。

socket.setTimeout(timeout[, callback])#

中英对照提交修改

当 socket 在 timeout 毫秒不活动之后将其设置为超时状态。默认 net.Socket 没有超时。

当一个闲置的超时被触发,socket 将会收到一个 'timeout' 事件,但连接不会被断开。用户必须手动调用 socket.end()socket.destroy() 来断开连接。

socket.setTimeout(3000);
socket.on('timeout', () => {
  console.log('socket 超时');
  socket.end();
});

如果 timeout 是 0,则存在的闲置超时将会被禁止。

可选的 callback 参数将会被当作一个时间监听器被添加到 'timeout' 事件。

socket.unref()#

中英对照提交修改

如果活跃的 socket 是事件系统中仅存的 socket,则调用 unref() 将会允许程序退出。对一个已经调用了 unref 的 socket 再调用 unref() 无效。

socket.write(data[, encoding][, callback])#

中英对照提交修改

在 socket 上发送数据。第二个参数制定了字符串的编码 - 默认是 UTF8 编码。

如果全部数据都成功刷新到内核的缓冲则返回 true。如果全部或部分数据在用户内中排队,则返回 false。当缓冲再次空闲的时候将触发 'drain' 事件。

当数据最终都被写出之后,可选的 callback 参数将会被执行 - 可能不会立即执行。

详见 Writable 流的 write() 方法。

net.connect()#

中英对照提交修改

net.createConnection() 的别名。

可能的签名:

net.connect(options[, connectListener])#

中英对照提交修改

net.createConnection(options[, connectListener]) 的别名。

net.connect(path[, connectListener])#

中英对照提交修改

net.createConnection(path[, connectListener]) 的别名。

net.connect(port[, host][, connectlistener])#

中英对照提交修改

net.createConnection(port[, host][, connectListener]) 的别名。

net.createConnection()#

中英对照提交修改

一个用于创建 net.Socket 的工厂函数,立即使用 socket.connect() 初始化链接,然后返回启动连接的 net.Socket

当连接建立之后,在返回的 socket 上将触发一个 'connect' 事件。若制定了最后一个参数 connectListener,则它将会被添加到 'connect' 事件作为一个监听器。

可能的签名有:

net.connect() 函数也是该函数的别名。

net.createConnection(options[, connectListener])#

中英对照提交修改

可选的选项,查看 new net.Socket([options])socket.connect(options[, connectListener])

附加的选项:

下面是在 net.createServer() 章节描述的 server 的客户端示例:

const net = require('net');
const client = net.createConnection({ port: 8124 }, () => {
  // 'connect' 监听器
  console.log('已连接到服务器');
  client.write('你好世界!\r\n');
});
client.on('data', (data) => {
  console.log(data.toString());
  client.end();
});
client.on('end', () => {
  console.log('已从服务器断开');
});

如果要连接到 /tmp/echo.sock,第二行只需要改为:

const client = net.createConnection({ path: '/tmp/echo.sock' });

net.createConnection(path[, connectListener])#

中英对照提交修改

初始化一个 IPC 连接。

该方法使用所有默认选项创建一个新的 net.Socket,使用 socket.connect(path[, connectListener]) 立即初始化连接,然后返回初始化连接的 net.Socket

net.createConnection(port[, host][, connectlistener])#

中英对照提交修改

初始化一个 TCP 连接。

这个函数用默认配置创建一个新的 net.Socket,然后 socket.connect(port[, host][, connectListener]) 初始化一个连接,并返回开启连接的那个 net.Socket

net.createServer([options][, connectionlistener])#

中英对照提交修改

  • options <Object>

    • allowHalfOpen <boolean> 表明是否允许半开的 TCP 连接。默认值: false
    • pauseOnConnect <boolean> 表明是否应在传入连接上暂停套接字。默认值: false
  • connectionListener <Function> 自动设置为 'connection' 事件的监听器。
  • 返回: <net.Server>

创建一个新的 TCP 或 IPC 服务器。

如果 allowHalfOpen 被设置为 true,则当套接字的另一端发送 FIN 数据包时,服务器将仅在 socket.end() 被显式调用发回 FIN 数据包,直到此时连接为半封闭状态(不可读但仍然可写)。 有关详细信息,参阅 'end' 事件和 RFC 1122(第 4.2.2.13 节)。

如果 pauseOnConnect 被设置为 true,则与每个传入连接关联的套接字会被暂停,并且不会从其句柄读取任何数据。 这允许在进程之间传递连接,而原始进程不会读取任何数据。 要从暂停的套接字开始读取数据,则调用 socket.resume()

服务器可以是一个 TCP 服务器或 IPC 服务器,这取决于 listen() 监听什么。

以下是一个 TCP 回声服务器的示例,在 8124 端口上监听连接:

const net = require('net');
const server = net.createServer((c) => {
  // 'connection' 监听器。
  console.log('客户端已连接');
  c.on('end', () => {
    console.log('客户端已断开连接');
  });
  c.write('你好\r\n');
  c.pipe(c);
});
server.on('error', (err) => {
  throw err;
});
server.listen(8124, () => {
  console.log('服务器已启动');
});

使用 telnet 测试:

$ telnet localhost 8124

要想在 /tmp/echo.sock 上监听,则最后三行需改为:

server.listen('/tmp/echo.sock', () => {
  console.log('服务器已启动');
});

使用 nc 连接到 Unix 域套接字服务器:

$ nc -U /tmp/echo.sock

net.isIP(input)#

中英对照提交修改

测试输入是否是 IP 地址。无效的字符串则返回 0,IPv4 地址则返回 4,IPv6 的地址则返回 6

net.isIPv4(input)#

中英对照提交修改

如果输入是 IPv4 地址则返回 true,否则返回 false

net.isIPv6(input)#

中英对照提交修改

如果输入是 IPv6 地址则返回 true,否则返回 false