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

2023-12-02

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


如果您真正想知道的是“如何检测丢失的数据包”?那么一般的技术是让接收方对发送的每个数据包发送确认。如果发送方没有收到确认,则必须重新发送数据包。如果接收方收到重复的数据包,那么它应该丢弃重复的数据包。

基本方案是这样的:

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 数据包与最后一个数据包不匹配,这意味着它与前一个数据包匹配。这意味着最后一个数据包尚未得到确认,这意味着出现了严重错误,应该重新传输数据包,直到收到正确的确认。

TX                               RX
 ╷           data[0]
 ╰──────────────────────────────▶

              ack[0]            ╷
 ◄──────────────────────────────╯

 ╷           data[1]
 ╰──────────────────────────────▶

              ack[0]            ╷
 ◄──────────────────────────────╯     ack mismatch!

 ╷       data[1] retransmit
 ╰──────────────────────────────▶

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

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

滑动窗口技术的一大优点是您可以发送大量数据包而无需等待确认。这显着提高了吞吐量:

TX                             RX
 ╷           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 是因为在某些情况下丢包是可以接受的(例如音频/视频流)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以在 Node.js 上使用 UDP 来保证消息的传递? 的相关文章

随机推荐

  • 加载引导加载程序的第二阶段

    我正在尝试为 x86 机器创建一个小型操作系统 并开始为相当小的引导加载程序编写代码 我创建的引导加载程序非常简单 它从位于主引导记录后面的扇区加载一个小的第二引导加载程序 并跳转到该代码 主引导记录中的引导加载程序代码似乎运行良好 当它尝
  • Inno Setup - 替换默认的下一步/后退/取消按钮

    我需要一种方法将我自己的按钮添加到向导页面 删除 Inno Setup 中的现有按钮 那可能吗 对的 这是可能的 code procedure AboutButtonOnClick Sender TObject begin MsgBox T
  • 如何从 MySQL 中的 DATETIME 字段中仅选择日期?

    我在 MySQL 数据库中有一个表 设置为DATETIME 我需要SELECT在此表中仅按日期显示 不包括时间 我如何SELECT在此表中仅按日期并绕过时间 即使该特定列设置为DATETIME Example 现在它是 2012 01 23
  • 按 SUM 对 Oracle 查询排序,而不选择 SUM

    我有一张类似于下面的表 lot defect quantity lot1 c 7 lot1 c 2 lot3 e 5 lot3 b 9 lot3 a 5 lot2 d 4 lot4 c 12 我想对行之间的批次和缺陷相等的数量求和 然后按数
  • 在新的 Facebook JavaScript SDK 中显示弹出窗口

    我曾经有一个href在我的网站上 当用户单击它时 会显示一个多朋友选择器 以便他们可以邀请他们的朋友访问我的网站 这是使用以下代码完成的 FB ensureInit function var dialog new FB UI FBMLPop
  • BST 时间错误

    使用下面的代码 每个时区都正确打印值 除了BST import java text def format yyyy MM dd HH mm ssXXX def dt new Date println dt SimpleDateFormat
  • iPhone创建聊天应用程序[关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我想在 iPhone 上创建一个聊天类应用程序 我知道我将如何实现一个轮询模型 其中 i
  • 在 C# 中将小数或字符串转换为货币的最佳方法?

    我一直在尝试根据我的选择找到将小数 字符串转换为货币的最佳方法 public static string returnWaluta string varS string varSymbol decimal varD decimal Pars
  • Bootstrap 自定义下载中的颜色?

    所以我使用 Bootstrap自定义和下载页面生成具有自定义颜色的 Bootstrap 文件版本 我的想法是我想添加一些其他颜色 例如 purpleLight 以使网站设计的维护更容易 所以我查看了网站生成的下载内容 并且我的自定义似乎不在
  • DocumentDB - 删除导致 401 错误

    当我尝试对 DocumentDB 集合执行 DELETE 动词时 我总是收到 401 错误 用于查询 插入 更新的 POST 工作正常 因此我确信计算授权令牌的代码是正确的 但我不确定应该为资源 id 和资源类型传递什么 payLoad L
  • 检查 firebase 数据库中是否存在值

    firebase中有没有一种方法可以检查数据库中是否存在值 Firebase有方法 exists 但根据文档它只检查密钥 我有以下结构 users KKUmYgLYREWCnWeHCvO fName Peter ID U1EL9SSUQ u
  • 在 R 中读取键值文件

    有没有办法在 R 中读取简单的文本键值文件 Key1 Value1 Key2 Value2 Key3 Value3 理想情况下 我想像这样访问数据 myfile Key1 应返回 Value1 myfile Key2 应返回 Value2等
  • WP8:无法使用本机组件

    Windows Phone 8 C 项目 MyApp 从 WP7 1 迁移 我添加了一个本机 Windows 运行时组件库 AppLib 到解决方案 创建了一个参考 有一个公共密封的参考类 MyClass 在里面 C 代码中有对它的引用 在
  • Python strptime 芬兰语

    我有一个日期的芬兰表示 蒂斯塔纳 27 lokakuuta 2015 我需要将其转换为日期时间对象 但是 Python 中的日期时间库无法识别日期和月份名称 我希望像下面这样的东西能够工作 import locale from dateti
  • 是否可以拦截应用程序卸载?

    是否可以拦截应用程序卸载并进行一些工作 例如 我的应用程序修改了设备的一些文件 因此在卸载我的应用程序所做的回滚更改之前会很整洁 有什么提示 想法吗 你在谈论类似的问题吗 应用程序卸载前收听广播 然后如上所述 您必须使用上面链接中给出的意图
  • 通过 PIP 安装 pyautogui 时获取“encoding”是此函数的无效关键字参数”

    当我尝试将 pyautogui 库安装到 python 时 出现此错误 请在下面找到详细信息 ERROR Complete output from command python setup py egg info ERROR Traceba
  • pandas - 按部分字符串分组

    我想按部分子字符串对 DataFrame 进行分组 这是一个示例 csv 文件 GridCode Key 1000 Colour 1000 Colours 1001 Behaviours 1001 Behaviour 1002 Favour
  • selenium webdriver C# 多线程

    Selenium WebDriver 支持多线程吗 我尝试在打开 2 4 个窗口的情况下使用它 看起来浏览器窗口 Firefox 有时会被冻结 当一个线程启动时 driver FindElement By Id id SendKeys My
  • Django 复杂注释

    先决条件 查询集必须返回Articles 查询集必须返回唯一的对象 不得使用访问数据库的 for 循环 意味着对要注释的 N 个对象进行 N 个查询 我的模型 class Report BaseModel ios report JSONFi
  • 是否可以在 Node.js 上使用 UDP 来保证消息的传递?

    如何在 Node js 上使用 UDP 保证消息的传递 例如 如果数据包失败 我可以重新发送数据包 但有没有办法识别它何时失败 另外 数据包丢失有多常见 如果您真正想知道的是 如何检测丢失的数据包 那么一般的技术是让接收方对发送的每个数据包