为啥 UDP + 一个软件可靠的订购系统比 TCP 更快?
Posted
技术标签:
【中文标题】为啥 UDP + 一个软件可靠的订购系统比 TCP 更快?【英文标题】:Why is UDP + a software reliable ordering system faster than TCP?为什么 UDP + 一个软件可靠的订购系统比 TCP 更快? 【发布时间】:2010-11-15 02:43:23 【问题描述】:今天的一些游戏使用通过 UDP 传输消息的网络系统,并确保消息可靠且有序。
例如,RakNet 是一个流行的游戏网络引擎。它仅使用 UDP 进行连接,并且有一个完整的系统来确保数据包的可靠性和有序性(如果您愿意的话)。
我的基本问题是,这是怎么回事? TCP 与有序的、可靠的 UDP 不是一回事吗?是什么让它变得如此缓慢以至于人们不得不重新发明***?
【问题讨论】:
【参考方案1】:一般/专业
-
TCP 是一个通用的可靠系统
UDP +任何特殊用途的可靠系统。
专业化的东西通常比通用的东西要好。
流/消息
-
TCP 是基于流的
UDP 是基于消息的
发送离散的游戏信息映射通常更适合基于消息的范例。通过流发送它是可能的,但非常无效。如果你想可靠地发送大量数据(文件传输),TCP 是相当有效的。这就是为什么 Bit-torrent 使用 UDP 发送控制消息和 TCP 发送数据的原因。
【讨论】:
【参考方案2】:大约一年前,我们在“英雄联盟”中从可靠转为不可靠,因为有几个优势后来被证明是正确的:
1) 旧信息变得无关紧要。如果我发送了一个健康包但它没有到达……我不想在知道它发生变化时等待同一个健康包重新发送。
2) 有时不需要订购。如果我向不同的系统发送不同的消息,则可能没有必要按顺序获取这些消息。我不强迫客户端等待有序消息。
3) 不可靠不会得到消息的备份...即等待确认,这意味着您可以更快地解决丢失峰值。
4) 您可以在必要时更有效地控制重新发送。例如重新包装没有发送到另一个数据包中的东西。 (TCP 确实会重新打包,但您可以通过了解您的程序如何工作来更有效地进行打包。)
5) 消息的流控制,例如在网络突然出现峰值时丢弃不太相关的消息。当您遇到丢失高峰时,网络系统可以选择不重新发送不太相关的消息。使用 TCP,您仍然会有一个尝试重新发送的消息队列,这些消息的优先级可能较低。
6) 较小的标头数据包...不需要多说。
【讨论】:
【参考方案3】:UDP 和 TCP 之间的区别远不止可靠性和顺序:
问题的核心在于 UDP 是无连接,而 TCP 是已连接。这个简单的差异导致了许多其他差异,我无法在此合理地总结。您可以阅读下面的分析以了解更多详细信息。
TCP - UDP Comparative Analysis
【讨论】:
【参考方案4】:在我看来答案就两个字:“拥塞控制”。
TCP 竭尽全力管理路径的带宽——充分利用它,但要确保有空间供其他应用程序使用。这是一项非常艰巨的任务,本质上不可能在 100% 的时间内使用 100% 的带宽。
另一方面,使用 UDP,人们可以制定自己的协议以尽可能快地将数据包发送到线路上 - 这使得该协议对其他应用程序非常不友好,但可以在短期内获得更多“性能” .另一方面,如果条件合适,这种协议很有可能会促成congestion collapse。
【讨论】:
【参考方案5】:TCP 是面向流的协议,而 UDP 是面向消息的协议。因此,TCP 所做的不仅仅是可靠性和排序。有关详细信息,请参阅this post。基本上,RakNet 开发人员增加了可靠性和排序,同时仍将其作为面向消息的协议,因此结果比 TCP 更轻量级(必须做更多)。
【讨论】:
【参考方案6】:这篇小文章很老了,但在游戏方面它仍然很真实。它解释了这两种协议,以及这些人试图开发多人网络游戏所造成的破坏。 “X翼对战平手”
Lessons Learned (The Internet Sucks)
对此有一个警告,我运行/开发了一款多人游戏,并且我都使用过。 UDP 对我的应用程序来说要好得多,但是很多人无法使用 UDP。路由器等阻止了连接。所以我改用“可靠”的TCP。嗯……可靠吗?我不这么认为。您发送一个数据包,没有错误,您发送另一个数据包,它在数据包中间崩溃(异常)。现在哪些数据包成功了?因此,您最终在 tcp 之上编写了一个可靠的协议,以模拟 UDP - 但在崩溃时不断建立新连接。拿一下效率低下。
UDP + 停止并等待 ARW = 好
UDP + 滑动窗口协议 = 更好
重新连接的 TCP + 滑动窗口协议? = 毫无价值的散装件。 (恕我直言)
另一个副作用是多线程应用程序。 TCP 适用于聊天室类型的东西,因为每个房间都可以是它自己的线程。一个房间可以容纳 60-100 人并且运行良好,因为房间线程包含每个参与者的套接字。
另一方面,UDP 最好由一个线程提供服务(IMO),但是当您获取数据包时,您必须解析它以找出它来自谁(通过发送的信息或 RemoteEndPoint),然后将该数据传递给以线程安全的方式聊天室线程。
实际上,您必须对 TCP 执行相同的操作,但仅在连接时。
最后一点。请记住,TCP 会随时出错并终止连接,但您可以在大约 0.5 秒内重新连接并发送相同的信息。我用过的最奇怪的东西。
【讨论】:
你能详细说明一下你使用TCP时抛出的异常吗?我肯定会责怪你的代码而不是 TCP 层,因为这听起来有点荒谬。感谢您指出滑动窗口协议,但我没有听说过它,这是一个有趣的算法。【参考方案7】:UDP 具有较低的可靠性,通过使其发送消息并等待响应来提供更高的可靠性,如果没有响应,它会重新发送消息。
【讨论】:
现有的答案有六个,其中一些已经过社区验证,其中大部分提供的细节远不止于此。虽然我们很高兴您渴望为社区做出贡献,但请将您的时间集中在您有新信息要添加的问题上。以上是关于为啥 UDP + 一个软件可靠的订购系统比 TCP 更快?的主要内容,如果未能解决你的问题,请参考以下文章