Networking 如何知道已收到哪些UDP数据包?

Networking 如何知道已收到哪些UDP数据包?,networking,udp,client-server,Networking,Udp,Client Server,我正在制作一个使用UDP的客户端-服务器模型的游戏。到目前为止,我是如何实现它的: 所有数据包都包含一个序列号和一个标志,指定它们是否“重要” 重要的消息类型需要确认,如果没有收到确认,将在延迟后重新发送 大多数消息类型都是“不重要的”——也就是说,它们不需要确认,如果接收到的此类消息的序列号比最新的序列号旧,则会将其丢弃 我的困境是:如果一条“重要”消息到达两次,我只想处理一次。但我怎么知道我已经收到了它,而不在记忆中保留一个不断扩展的列表呢 想法 只需记住收到的最后X条“重要”消息-收到

我正在制作一个使用UDP的客户端-服务器模型的游戏。到目前为止,我是如何实现它的:

  • 所有数据包都包含一个序列号和一个标志,指定它们是否“重要”
  • 重要的消息类型需要确认,如果没有收到确认,将在延迟后重新发送
  • 大多数消息类型都是“不重要的”——也就是说,它们不需要确认,如果接收到的此类消息的序列号比最新的序列号旧,则会将其丢弃
我的困境是:如果一条“重要”消息到达两次,我只想处理一次。但我怎么知道我已经收到了它,而不在记忆中保留一个不断扩展的列表呢

想法

  • 只需记住收到的最后X条“重要”消息-收到非常旧消息的可能性很小(不理想,因为它不是100%可靠)
  • 将TCP用于“重要”消息(由于同时管理两个协议涉及的复杂性和开销,因此不理想)
  • 为“重要”消息设置单独的序列号,并确保这些消息总是按顺序接收,因此只需要记住最近的消息(我倾向于这样)
  • 还有其他想法吗

  • 为“重要”消息(从零开始)和以下变量提供单独的序列号:

    • 变量
      min\u recv
      ,表示您收到了从0到
      min\u recv
      (不包括)的所有“重要”消息
    • 您已经收到的“重要”序列号列表
    在任何时候(例如,在收到另一条“重要”消息后),您将其序列号存储在列表中;然后,您可以检查是否可以压缩列表:

    while list contains `min_recv`:
        remove `min_recv` from list
        increment min_recv
    

    通过这种方式,您将消耗最少的内存,因为即使您接收到无序的重要消息(并且列表的大小将开始增长),最终您也会收到丢失的消息,因为丢失的消息将被重新传输,您将清空列表。

    使用#3。您确认重要消息的事实提供了确保按顺序接收的机制,即不要确认顺序错误的消息,只需记住您确认的最后一条消息的序列号即可。

    谢谢您,这听起来是一种支持无序消息并保证传递的好方法。不确认无序消息将导致超时窗口中所有其他接收消息的延迟。只有当您无法在内存中存储大量消息时,我才会选择此解决方案。