许多游戏开发人员选择在应用程序级别使UDP 可靠。这不就是 TCP 的用途吗?我制作了一个 API,可以使用 UDP 和 TCP 数据包实现客户端-服务器通信。我应该将可靠的 UDP 添加到列表中吗?为什么?如果我使用 TCP 会有问题吗?
我只想知道RUDP是否比 TCP 有任何好处,以便我可以选择是否添加 RUDP 支持。
许多游戏开发人员选择在应用程序级别使UDP 可靠。这不就是 TCP 的用途吗?我制作了一个 API,可以使用 UDP 和 TCP 数据包实现客户端-服务器通信。我应该将可靠的 UDP 添加到列表中吗?为什么?如果我使用 TCP 会有问题吗?
我只想知道RUDP是否比 TCP 有任何好处,以便我可以选择是否添加 RUDP 支持。
简短的回答:TCP 没有针对延迟进行优化(根本没有);结果 - 它有几个属性是游戏的延迟杀手(尽管它们只有在数据包丢失时才会发挥作用)。特别是,对于快节奏的游戏来说,线头阻塞和指数退避往往非常烦人。
对延迟影响最大的是线头阻塞(又名 HOL 阻塞):如果一个数据包丢失,则同一流中的所有后续数据包,即使它们到达通信的另一端,也不允许到达应用程序级别(哎哟!),直到丢失的数据包被重新传输(这将花费大约 2*RTT,即使对于每个大陆的服务器,也大约是 100 毫秒(=“在射击游戏中,你已经被杀死了))。
长答案:
这是一个复杂的主题,我们需要区分几个不同的场景:
我们确实需要可靠的有序消息(或字节)流。在这种情况下,RUDP 相对于 TCP 的好处虽然存在,但非常小(我们可以在减少重传时间方面发挥一点作用——并消除指数回退,但仅此而已)。特别是,对于任何类型的可靠有序流(无论是 TCP、RUDP 还是其他),线头阻塞仍然是不可避免的。
我们确实需要可靠但可能无序的消息传递。这可以避免 HOL 阻塞,但需要相当复杂的应用级处理。
我们根本不需要可靠性(“一劳永逸”)。此类信息的一个主要示例是当我们需要显示子弹击中时 - 如果我们没有立即显示它,那么半秒后就不需要显示它,所以如果数据包没有成功 - 好吧,最好忽略它,而不是花费资源重新发送数据包。
我们确实需要最终同步的状态(但我们不关心经历所有中间状态);这是一个非常常见的模拟场景。这可以通过 UDP 实现(并且不会产生 HOL 阻塞惩罚)。但是 - 在不可靠的连接上启用压缩并非易事,并且对于大多数游戏来说,压缩是必须的。幸运的是 - 这种压缩是可行的(参见http://gafferongames.com/networked-physics/snapshot-compression/和/或http://ithare.com/udp-from-mog-perspective/#low-latency-compression供讨论)。如果实施这种方法(可以在完全不可靠的数据包之上完成) - 它将提供比 TCP 非常显着的改进(它确实消除了 HOL 阻塞,所以我们谈论的是网络滴答顺序的延迟 - 这可以低至 1/120 秒~= 8 毫秒 - 超过 RTT 周围的延迟,对于一个丢失的单个数据包,这些至少为 100 毫秒)。
旁注:
实际上,可以通过 TCP 模拟 UDP(消除 TCP 延迟) - 请参阅http://ithare.com/almost-zero-additional-latency-udp-over-tcp/。请注意,要使用它,上述所有内容仍应手动完成。仍然没有灵丹妙药可以避免可靠有序流的 HOL 阻塞;相反 - 这种技术允许建立多个 TCP 连接以表现“几乎就像”它是不可靠但非阻塞的 UDP。
问题在于乱序数据包。
在查看之后,我了解到问题是 TCP 想要占用所有接收到的数据包,直到它们按照应用程序期望的顺序接收。这可能对合理规模的多人游戏的性能相当不利,在这种游戏中,您只关心最新的玩家位置,而不是它们恰好在几毫秒前的位置。
正如来自 Unity 的 Erik 所说, RUDP改变了这一切,只提供“最新数据包”:
Erik-Juhl @ Unity Technologies
人们选择 UDP/RUDP 而不是 TCP 的主要原因是 TCP 处理乱序数据包的方式。您可能只关心最近收到的数据包,并在它到达时想要它。在 TCP 中,如果您最近收到的数据包不是按顺序排列的下一个数据包,则 TCP 将不会将其交付给您,直到其他所有数据都已收到。
如果您需要保证顺序和交付,那么只需使用TCP。如果您需要保证顺序和交付以及在最新数据包到达时立即获取它们,请使用 RUDP。 告诉我更多...
如果我直接说 UDP 比用于此类应用程序的 TCP 更快;你不会相信和接受。开发人员在此基础上开发了 UDP (称为 RUDP)的一些可靠性,使其在某种程度上模仿 TCP。尽管如此,它并没有完全(总体上)实现 TCP 功能。
这就是为什么我想参考一篇文章来回答你的问题Reliable UDP (RUDP): The Next Big Streaming Protocol?
:
TCP 有一组指令可确保每个数据包都到达其接收者。它可以与最基本形式的记录交付相媲美。然而,虽然起初看起来很明显“确保消息到达那里”在向其他人发送内容时至关重要,但还有一些额外的注意事项必须注意。如果使用 TCP/IP 的网络链接注意到一个数据包已乱序到达,则 TCP 停止传输,丢弃乱序数据包中的任何内容,发送“返回错误的地方”消息,然后再次开始传输。
如果你有世界上所有的时间,这很好。因此,为了将我的工资信息从我的公司传输给我,坦率地说,我不在乎这需要一微秒还是一个小时,我希望它正确完成。TCP 非常适合这一点。
然而,在以视频为中心的服务模型中,数据太多了,以至于如果一些数据包无法通过链接,在某些情况下,我宁愿跳过这些数据包并继续处理整个视频流,而不是获取原始来源的每一个细节。只要不被生涩的音频和定格视频分散注意力,我们的大脑就可以为我们想象视频中跳过的部分。在这些情况下,无论有多少准确通过,都可以选择及时从链路的一端向另一端发送尽可能多的数据,这显然是可取的。对于这种类型的应用程序,UDP 是最佳的。如果一个数据包似乎没有到达,那么接收者会等待片刻以查看它是否到达——可能直到观众需要看到该视频块的那一刻——以及缓冲区是否到达这一点丢失数据包应该在哪里,然后继续,应用程序跳过丢失数据所在的点,继续下一个数据包并保持视频的时间基准。您可能会看到闪烁或一些伪影,但这一刻几乎立即过去,您的大脑很可能会填补空白。
如果在 TCP 下发生此错误,则 TCP 可能需要3 秒以上的时间来重新协商,以便从丢失的点重新启动序列,丢弃所有后续数据,这些数据必须重新排队才能再次发送。仅仅一个丢失的数据包就可能导致整个 TCP 数据“窗口”被重新发送。
许多游戏开发人员选择在应用程序级别使 UDP 可靠。这不就是 TCP 的用途吗?
如果您可以容忍两端处理数据的速度,那就可以了。
但是,在游戏中,这是不行的。您必须每秒多次将视频帧(和音频等)传递给许多玩家(如果是多人游戏)。这一切都需要更快的速度和更快的数据处理能力;而不是使用相对较慢的 TCP。即使中途丢弃了一些数据包,应用程序也可以继续运行,因为大脑也会继续下一个,而不是考虑那些抖动。
我制作了一个 API,可以使用 UDP 和 TCP 数据包实现客户端-服务器通信。我应该将可靠的 UDP 添加到列表中吗?为什么?如果我使用 TCP 会有问题吗?
这取决于您希望应用程序的响应能力有多好。我建议您将 Reliable UDP 添加到您的列表中。
我已经提到了 TCP 的问题。
我只想知道 RUDP 是否比 TCP 有任何好处,以便我可以选择是否添加 RUDP 支持。
凭借低开销和更高的速度,我敢打赌可靠的 UDP,而不是笨重的 TCP - 用于开发此类应用程序(游戏)。
我对这些协议不是很了解,但是根据我目前的了解,TCP是面向连接的协议,UDP是无连接的协议。UDP 主要用于实时在线多人游戏,因为 UDP 更快,因为不尝试错误恢复。在那些游戏中,使用 UDP 是因为可靠性并不重要。TCP 采取措施确保客户端接收到所有发送的数据包,而 UDP 只是发送它们而不检查它们是否已被接收。如果我错了,请纠正我!