【发布时间】:2011-11-11 19:05:09
【问题描述】:
互联网上有几篇关于如何使 udp 可靠的文章。我一直无法在 c# 上找到一个。所以也许我可以实现我的算法。
从网上研究我认为udp有两个问题:
- 它不能确保所有数据都到达它的目的地。
- 数据可能会以不同的顺序到达目的地
- 也许我还遗漏了第三个问题,以使其可靠
如果您有兴趣了解我为什么要使 udp 可靠以及为什么不使用 tcp,请查看 this question。相信我,我一直在尝试做 tcp 打孔。
无论如何,也许已经有一个库可以与 c# 一起使用,这将使我能够做到这一点。因为我注意到能够找到一个库,所以我一直在考虑以下算法:
“假设有计算机 A 和计算机 B,而计算机 A 是向计算机 B 发送文件的那一台”;
这是我一直在考虑的步骤:
1) 计算机 A 打开文件进行读取,假设它是 5000 字节。这意味着计算机 A 必须向计算机 B 发送 5000 个字节,以确保没有字节丢失并且顺序正确。
2) 计算机 A 获取文件的前 500 个字节,并获取这些字节的哈希值。所以现在计算机 A 有两件事是这 500 个字节的哈希值和字节数。 (哈希将是一种有效的算法,例如 md5,以确保以正确的顺序接收数据。即 md5(1,2,3) != md5(2,1,3))
3) 将前 500 个字节的散列成像结果是 kj82lkdi930fi1。
4) 计算机 B 应该正在侦听哈希和字节。
5) 计算机 A 将哈希发送到计算机 B。它也发送 500 个字节。一旦它发送它就开始等待回复。
6) 计算机 B 现在应该接收散列和字节。计算机 b 对接收到的字节执行相同的算法 md5。如果该结果等于接收到的散列,则它以 {1,1,1,1,1,1} 回复 A 否则它以 {2,2,2,2,2,2,2} 回复
6.5) 假设计算机 B 以正确的顺序获取数据,因此它回复 {1,1,1,1,1,} 它还将哈希码保存在内存或数组中。
7) 计算机 A 应该等待响应以发送接下来的 500 个字节。假设它收到 {1,1,1}。因为它收到了 1,所以它知道它可以继续并使用这 500 个字节的新哈希码发送接下来的 500 个字节。
8) 计算机 A 发送接下来的 500 个字节及其哈希码。
9) 假设计算机 B 没有收到数据,因此它不会回复 A。计算机 B 仍将等待字节和哈希
8) 由于计算机 A 在合理的时间内没有收到 1,1,1,1,1 或 2,2,2,2,2,那么 A 将发送相同的字节并再次散列第二次。
9) 假设计算机 B 接收到哈希和字节,但接收到的字节顺序不同。当计算机 B 计算这些字节的散列时,该散列将与接收到的散列不匹配。结果它会回复 {2,2,2,2,2,2}
10) 如果计算机 A 接收到 2,2,2,2,2,2 那么它将发送相同的字节和散列。如果由于某种原因它没有收到 2,2,2,2,2 那么它会在一段时间后发送相同的字节和散列。假设计算机 A 收到 2,2,2,2,2
11) 计算机 A 第三次发送相同的字节和散列。
12) 计算机 B 以正确的顺序接收哈希和字节。结果,它回复 1,1,1,1,1,1 并将之前的哈希值保存在内存中。 (回忆第 6.5 步)
13) 假设计算机 A 没有收到 B 的 1,1,1,1 响应。然后它将第四次发送相同的字节。
14) 计算机 B 检查哈希值,如果它等于最后一个被接受的哈希值,则它再次回复 1,1,1,1 而不将这些字节写入文件。
15) 算法继续如此,直到文件被传输。
.
.
.
我的意思是显然还有一些其他的事情我需要添加到这个算法中,比如让计算机 B 知道传输何时完成。也许检查更多错误。如果计算机A长时间断开连接会发生什么。但主要协议将类似于我描述的协议。
那么你认为我应该开始实现这个算法吗?我应该每次增加并发送更多字节吗?我的意思是发送 1000 而不是 500?互联网上有很多文章向您介绍了几种技术,但很少有文章为您提供所需语言的工作示例。在这种情况下,我需要在 c# 中使用它。
【问题讨论】:
-
因为tcp打孔很难做!相信我,如果我可以使用 tcp 协议连接不同 nat 上的两个对等点,那么我不会浪费时间问这个问题。看看这个问题:stackoverflow.com/questions/7225150/…。为了创建 tcp 打孔,我无法在 Internet 上找到示例。我找到了几篇解释它是如何工作的文章,但是当我将这些文章翻译成 c# 时,由于某种原因它们不起作用。
标签: networking udp file-transfer reliability