如何在Node.js上保证使用UDP传递消息?例如,如果数据包失败,我可以重新发送数据包 - 但有没有办法确定它何时失败?另外,数据包丢失有多常见?
答案 0 :(得分:7)
如果您真正想知道的是“我如何检测丢失的数据包”?然后,一般技术是让接收器发送对每个分组的确认。如果发送器没有收到确认,则必须重新发送数据包。如果接收者获得重复的数据包,那么它应该丢弃副本。
基本方案是:
TX RX
\ data
`----------------------------->
ack /
<-----------------------------'
\ data
`-------------------- - - - loss of data packet
.
.
. timeout
.
\ data retransmit
`----------------------------->
ack /
<-----------------------------'
\ data
`----------------------------->
ack /
- - - - -----------------' loss of ack packet
.
. timeout
.
\ data retransmit
`----------------------------->
ack /
<-----------------------------'
这基本上是所有形式的丢包检测的基础。有几个改进可以实现以改进技术,但基本原理通常是相同的:如果接收器没有告诉你数据包已经到达,那么数据包就会丢失。
一第一改进通常做的算法是检查该ACK是真正的适当ACK,而不仅仅是一些回波由路由器或由信号交叉inteference或由软件错误发送。解决方案是实现切换位。数据包在切换位设置为一个值的情况下传输,并且ack数据包需要回复适当的值(通常是相同的值)。如果切换位错误则意味着ack包与最后一个数据包不匹配,这意味着它与先前的数据包匹配。这意味着最后一个数据包尚未被确认,这意味着某些内容严重出错并且应该重新发送数据包,直到收到正确的确认。
TX RX
\ data[0]
`----------------------------->
ack[0] /
<-----------------------------'
\ data[1]
`----------------------------->
ack[0] /
<-----------------------------' ack mismatch!
\ data[1] retransmit
`----------------------------->
一些现实世界的协议使用这种技术,包括用于控制工业设备和机器人的大多数协议。
下一步实际上是对上述想法的扩展。而不是发送一点为什么不发送一个数字。这样您就可以更加明确地将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
`----------------------------->
因此,以上是检测数据包丢失的基本技术的简短摘要。如果您希望所有UDP数据包到达目的地,那么您需要实现这一目标。
你应该知道TCP已经实现了这一点,所以你真的应该使用TCP,如果你不想重新发明轮子。创建UDP是因为在某些情况下丢包是正常的(想想音频/视频流)。
答案 1 :(得分:2)
来自维基百科
UDP适用于不需要或在应用程序中执行错误检查和纠正的目的,从而避免了在网络接口级别进行此类处理的开销。时间敏感的应用程序通常使用UDP,因为丢弃数据包比等待延迟数据包更可取,这在实时系统中可能不是一种选择。[2]如果在网络接口级别需要纠错功能,则应用程序可以使用为此目的而设计的传输控制协议(TCP)或流控制传输协议(SCTP)。
如果您关心,基本上使用TCP,如果数据包/消息到达那里。否则,在应用程序级别使用UDP重新创建TCP。
答案 2 :(得分:0)
无法保证在任何平台上传送特定的UDP数据包,而不仅仅是node.js.如果您正在寻找的是基于UDP的可靠传送机制,请查找类似e-net的内容或搜索可靠的UDP。
编辑:或使用TCP。
答案 3 :(得分:0)
UDP是一种无法保证交付的协议。如果你想保证,你应该在UDP之上实现一些协议。