阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      Node.js dgram socket.send

      Node.js dgram socket.send(msg[, offset, length], port[, address][, callback]) 版本历史

      版本变更
      v8.0.0The msg parameter can be an Uint8Array now.
      v8.0.0The address parameter is always optional now.
      v6.0.0On success, callback will now be called with an error argument of null rather than 0.
      v5.7.0The msg parameter can be an array now. Also, the offset and length parameters are optional now.
      v0.1.99新增于: v0.1.99
      • msg < Buffer> || < string> | < Array> 要发送的消息。
      • offset < number> 整数。指定消息的开头在 buffer 中的偏移量。
      • length < number> 整数。消息的字节数。
      • port < number> 整数。目标端口。
      • address < string> 目标主机名或 IP 地址。
      • callback < Function> 当消息被发送时会被调用。

      在 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 的情况下才能被使用。

      一个发送 UDP 包到localhost上的某个随机端口的例子:

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

      一个发送包含多个 buffer 的 UDP 包到 127.0.0.1 上的某个随机端口的例子:

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

      发送多个 buffer 的速度取决于应用和操作系统。 逐案运行基准来确定最佳策略是很重要的。但是一般来说,发送多个 buffer 速度更快。

      关于 UDP 包大小的注意事项

      IPv4/v6数据包的最大尺寸取决于MTU(Maximum Transmission Unit, 最大传输单元)与Payload Length字段大小。

      • Payload Length字段有16 位宽,指一个超过 64K 的包含 IP 头部和数据的负载 (65,507 字节 = 65,535 − 8 字节 UDP 头 − 20 字节 IP 头部);通常对于环回地址来说是这样,但这个长度的数据包对于大多数的主机和网络来说不切实际。

      • MTU指的是数据链路层为数据包提供的最大大小。对于任意链路, IPv4所托管的MTU最小为68个字节,推荐为576(典型地,作为拨号上网应用的推荐值),无论它们是完整地还是分块地抵达。

      对于IPv6, MTU的最小值是1280个字节,然而,受托管的最小的碎片重组缓冲大小为1500个字节。现今大多数的数据链路层技术(如以太网),都有1500的MTU最小值,因而68个字节显得非常小。

      要提前知道数据包可能经过的每个链路的 MTU 是不可能的。发送大于接受者MTU大小的数据包将不会起作用,因为数据包会被静默地丢失,而不会通知发送者该包未抵达目的地。


      更多内容请参考:Node.js debugger 调试器,或者通过 点击对应菜单 进行查看;


      目录
      目录