用于重建udp会话的结构是什么?

时间:2012-03-07 21:40:05

标签: c# udp

我是实施股票exachange引擎。 我通过UDP接收股票代码数据,每个udp组播数据包都有序列号。 Exchange一个接一个地发送数据包,但由于UDP不保证它们可能(并且将会)以轻微的“混合”顺序接收,例如:

1 2 3 5 4 6 7 10 9 8 11 12 13 14 15

假设我按正确顺序接收数据包,一切都会很简单 - 我可以使用Queue添加数据包并在以后将它们出列。但由于数据包没有完全排序,我有几个问题:

  • 用于存储数据包的结构是什么?我需要能够排队和出队数据包,我还需要能够在数组
  • 中的任意位置添加数据包
  • 如果某个数据包丢失,我需要升级“恢复”程序。因此,每当“nextPacketSequenceNumber!= currentPacketSequenceNumber + 1”时,我应该等待5毫秒,可能数据包将到达,如果不是,我应该恢复。例如

    1 2 3 5 ... after 5 ms .... 4   - OK
    1 2 3 5 ... after 10 ms .... 4 - recover
    1 2 3 5 6 7  - recover
    

4 个答案:

答案 0 :(得分:0)

您可以使用priority queue来解决重新排序问题,将序列号作为键(优先级)。最简单的优先级队列只是一个有序字典。可以使用优先级队列和闹钟的组合来解决恢复问题。

答案 1 :(得分:0)

这可能不是最有效的方法,但我已经使用OrderedDictionary(虽然SortedDictionary可能更合适)来处理过去的乱序问题。使用序列号作为密钥,将数据包数据作为值。

不幸的是,我不能说你的第二个问题(没有多少努力)。我唯一建议的是扩展你的协议以允许召回类型的消息,这些消息可以由接收方发送给发起者,告诉他们重新发送数据包,因为原始文件被删除了。我有这样的逻辑(只是更复杂),虽然它是公司财产,所以我不能分享它。希望这足以让你过去。

答案 2 :(得分:0)

如果排序很关键,问题会变得更加复杂 - 例如,您可以使用优先级队列,但除了序列中的下一个之外,您也不希望处理队列中的任何内容。因此,您可能希望实现一个优先级队列,该队列也会根据序列进行阻塞。

在这种情况下,您可能希望在找到丢失的数据包后立即在单独的线程中启动恢复过程 - 没有必要等待 - 如果数据包到达那么好,您可以忽略恢复结果。

这类似于音频流中的抖动缓冲,以重新排序UDP数据包。http://en.wikipedia.org/wiki/Jitter#Jitter_buffers

答案 3 :(得分:0)

因为序列号是连续的整数,所以数组非常适合存储。但它们也无休止地推进,因此您希望循环方式的索引重用,如环形缓冲区。

另一种看待它的方法是作为具有随机访问的环形缓冲区(不仅仅是FIFO)。