是否可以保证在Node.js上使用UDP传递消息?

Mai*_*tor 2 udp node.js

如何在Node.js上使用UDP保证传递消息?例如,如果数据包失败,我可以重新发送数据包 - 但有没有办法确定它何时失败?另外,数据包的丢失有多常见?

sle*_*man 7

如果您真正想知道的是"我如何检测丢失的数据包"?然后,一般技术是让接收器发送对每个分组的确认.如果发送器没有收到确认,则必须重新发送数据包.如果接收者获得重复的数据包,那么它应该丢弃重复的数据包.

基本方案是这样的:

TX                               RX
 \           data
  `----------------------------->

              ack               /
 <-----------------------------'

 \           data
  `-------------------- - - -          loss of data packet
               .
               .
               . timeout
               .
 \       data retransmit
  `----------------------------->

              ack               /
 <-----------------------------'

 \           data
  `----------------------------->

              ack               /
      - - - - -----------------'       loss of ack packet
               .
               . timeout
               .

 \       data retransmit
  `----------------------------->

              ack               /
 <-----------------------------'
Run Code Online (Sandbox Code Playgroud)

这基本上是所有形式的丢包检测的基础.有几个改进可以实现以改进技术,但基本原理通常是相同的:如果接收器没有告诉你数据包已经到达,那么数据包就会丢失.

通常对该算法进行的第一个改进之一是检查ack是否真的是适当的ack,而不仅仅是路由器发送的某些回声,或者是信号交叉干扰或软件错误.解决方案是实现切换位.数据包在切换位设置为一个值的情况下传输,并且ack数据包需要回复适当的值(通常是相同的值).如果切换位错误则意味着ack包与最后一个数据包不匹配,这意味着它与先前的数据包匹配.这意味着最后一个数据包尚未被确认,这意味着某些内容严重出错,并且应该重新发送数据包,直到收到正确的确认.

TX                               RX
 \           data[0]
  `----------------------------->

              ack[0]            /
 <-----------------------------'

 \           data[1]
  `----------------------------->

              ack[0]            /
 <-----------------------------'      ack mismatch!

 \       data[1] retransmit
  `----------------------------->
Run Code Online (Sandbox Code Playgroud)

几种现实世界的协议使用这种技术,包括用于控制工业设备和机器人的大多数协议.

下一步实际上是对上述想法的扩展.而不是发送一点为什么不发送一个数字.这样你就可以更加明确地将ack与数据包匹配,从而更准确地检测哪个数据包丢失并需要重传.这种技术通常被称为滑动窗口技术,因为在某些时候数字翻转并滑回零.因此,在您无法检测到丢包之前可以传输的最大数据包数是滑动窗口大小.

滑动窗口技术的最大优点是您可以在不等待确认的情况下发送大量数据包.这显着提高了吞吐量:

 \           data[1]
  `----------------------------->
 \           data[2]
  `----------------------------->
 \           data[3]
  `----------------------------->


              ack[1]            /
 <-----------------------------'
              ack[2]            /
 <-----------------------------'

 \           data[4]
  `----------------------------->
 \           data[5]
  `----------------------------->

              ack[3]            /
 <-----------------------------'
              ack[5]            /
 <-----------------------------'      ack[4] missing!
               .
               . timeout
               .

 \       data[4] retransmit
  `----------------------------->
Run Code Online (Sandbox Code Playgroud)

因此,以上是检测数据包丢失的基本技术的简短摘要.如果您希望所有UDP数据包到达目的地,那么您需要实现这一点.

您应该知道TCP已经实现了这一点,因此如果您不想重新发明轮子,则应该使用TCP.创建UDP是因为在某些情况下丢包是可以的(想想音频/视频流).