游戏服务器:到底使用UDP还是TCP
原创转自:http://blog.jobbole.com/64638/
写网络游戏时,如何使用UDP还是TCP迟早,我们必须面对这个问题。
一般来说,你会听到人们说:“除非你正在写一个动作游戏,否则你会使用TCP吧” 或者是 您可以MMO游戏中用TCP,因为魔兽世界使用它TCP!”
不幸的是,这些观点都没有反映这个问题的复杂性。
背景
首先,澄清一下,我主要使用TCP执行网络编程。几年来,我一直在为一款流行的在线纸牌游戏编写服务器,在高峰期,我们的每台服务器都可以承受4000到10000多个连接(在同一台物理计算机上运行的多个服务器进程)没有问题。在我看来,TCP这是一个安全和常见的选择。
尽管如此,我们的最新项目正在使用UDP协议,我们的项目无法通过任何方式实现TCP开始工作吧。事实上,最初使用TCP但后来发现我们正在使用TCP当我们无法满足所需的连接数时,我们只能将其替换为UDP了。
在使用中TCP你表现如何
原则上,TCP优点是:
- 简单直接的长连接
- 可靠的信息传输
- 数据包的大小没有限制
任何一个和TCP处理过它的人都知道,要实现稳定的TCP网络连接需要处理各种隐藏的陷阱,例如断开连接检测、客户端响应缓慢阻塞数据包以及各种类型的开放连接dos攻击、阻止和非阻止IO模型等
除了上面列出的问题之外,还有一个很好的问题TCP该模块确实很难编码和实现。
但是,TCP最糟糕的功能是它对阻塞的控制。一般而言TCP假设丢包是由网络带宽不足引起的,当出现这种情况时,TCP它会降低收缩的速度。
在3G或WiFi接下来,数据包丢失。您想要的是立即重新发送此数据包,但是TCP阻塞机制完全以相反的方式处理!
并且没有办法绕过这种机制,因为它是TCP协议构建的基础。这就是为什么在3G或者WiFi环境下,ping价值可以上升到1000多毫秒的原因。
为什么不使用它UDP
UDP相对TCP这既简单又难说。
例如UDP它是基于数据包构建的,这意味着在某些方面,你需要完全颠覆TCP在概念下。UDP仅使用一个socket沟通,不像TCP需要建立一个socket连接。这些都是UDP一个非常好的地方。
但是,在大多数情况下,您只需要一些连接概念,一些基本的数据包排序功能以及所谓的连接可靠性。不幸的是,这些功能UDP没有办法简单地提供给你,你使用它TCP但它们都可以免费获得。
这就是为什么人们经常推荐它TCP原因何在。使用中TCP您可以忽略这些问题,直到您需要将连接同步到一个数量级500当上面提到时。
所以,是的,UDP没有提供所有的解决方案,但如您所见,这也是UDP一个方便使用的地方。从某种意义上说,TCP对UDP就好比是Hibernate和手写SQL的区别。
使用TCP失败的地方
人们经常给你使用它的建议TCP,比如“TCP跟UDP同速“或”游戏X用TCP如此成功,如此TCP当然,这是第一选择,“但是,他们完全不明白为什么在那个特定的游戏中。TCP有效,为什么UDP为什么不按顺序发送数据包?
那么为什么魔兽世界采用TCP怎么样?首先,我们需要解释这个问题。问题实际上是“为什么魔兽世界有时会1000超过毫秒的延迟仍然可以运行吗 这是TCP的性质决定了当数据包丢失发生时,会有巨大的延迟,因为TCP首先,它将检测哪些数据包丢失,然后重新发送所有丢失的数据包,直到它们全部被接收。
可靠的UDP也有延迟,但因为它在UDP在此基础上建立的通信协议可以通过多种方式减少,这与TCP一切都取决于TCP协议本身无法更改。
在这一点上,有些人需要开始提及Nagle算法,事实上,它是你实现任何延迟敏感的TCP建模时需要禁止的第一件事。
那么魔兽世界和其他游戏如何处理延迟问题呢?
该方法也非常简单,它们可以隐藏延迟的影响。
在《魔兽世界》中,玩家和玩家是不能碰撞的:因为这种碰撞不能通过某种预测来处理,但玩家和环境之间的碰撞可以通过预测来处理。因此,TCP没有问题。
如果我们看一下《魔兽世界》中的战斗,我们会发现玩家的攻击命令向服务器发送的动作都放在了诸如” attack_entity(entity_id) ”或者” cast_spell(entity_id, spell_id) 换句话说,目标定位操作与执行无关。这样,发起攻击、释放技能等一些特殊效果就可以在不接收服务端确认的情况下直接执行,比如显示冻结技能的效果,可以在服务端返回数据之前在客户端完成。
客户端直接开始计算,无需等待服务器的确认,这是一种典型的隐藏延迟的技术。
几年前,我为一个名叫”Five Card Jazz“我为纸牌游戏写了一个客户。它使用http协议,比直接协议更有效TCP协议连接的延迟更为严重。
我们使用简单的卡片绘制和绘图动画来掩盖延迟问题,因此延迟问题仅在连接非常差的情况下才明显。这种方法也很典型:在发送请求的同时开始播放牌表的动画,继续玩和翻转最后一张牌,直到收到服务端发回的数据。《魔兽世界》的战斗效果也采用了类似的原理。
这也意味着我们正在使用TCP还是UDP这取决于我们是否可以隐藏延迟。
TCP什么时候到期
一个采用TCP游戏必须能够处理突然的延迟问题(就像卡客户端的典型情况一样,玩家不会抱怨突然的一秒延迟)或有很好的方法来缓解延迟问题。
但是,如果您正在运行的游戏无法使用任何延迟缓解措施,该怎么办?玩家对玩家的动作游戏通常属于这一类,但这不仅限于动作游戏。
例如:
我目前正在开发一款多人游戏(War Arcana)。
一个常见的操作是在充满战争迷雾的世界地图中快速移动你的角色,但是一旦你探索它,迷雾就会被打开。
为了保证游戏规则,防止玩家作弊,服务器只能显示玩家当前位置附近的信息。这意味着与魔兽世界不同,玩家无法在没有收到服务器响应的情况下完成操作。和Five Card Jazz相比之下,即使我们允许500毫秒的延迟已经非常困难了。
在实现游戏原型后,局域网上的一切都非常顺利,但是当我们WiFi在环境中进行测试时,操作可能会间歇性地卡住或出现高延迟。在编写了一些测试程序后,我发现,WiFi环境中偶尔会发生数据包丢失行为,每当发生数据包丢失时,服务器的响应速度都会从100-150毫秒上升到1000-2000毫秒。
没有办法绕过它TCP此设置用于避免此问题。
我们替换了它TCP代码是定制的,可靠UDP为此,将大量丢包造成的延迟减少到仅50毫秒,甚至比以前更多TCP往返延迟甚至更小,而不会丢失数据包。当然,这只能根据UDP除此之外,我们可以完全控制可靠性。
混淆:可靠UDP只是TCP一个简单的实现?
你听说过“可靠”这句话吗UDP就像TCP一样,所以我仍然使用它TCP吧”。
问题是这种说法是不正确的。可靠UDP没有外表的TCP,要去实现一个特殊阻止控制。事实上,这也是你使用可靠UDP代替TCP这样做的最大原因是为了避免TCP阻止控制。
另一个关键点是可靠性UDP如何保证可靠性。有很多方法可以实现这一点。我非常喜欢它Quake3网络库代码中的一些想法也启发了我War Arcana中使用UDP协议。
您还可以使用许多支持可靠通信的设备UDP当然,就可靠性而言,与手动实现所有代码本身相比,库可能更通用,并且失去了一些性能优势。
底线
那么到底在用什么UDP还是TCP呢?
- 如果客户端间歇性地启动无状态查询,并且偶尔的延迟是可以容忍的,请使用 HTTP/HTTPS 吧。
- 如果客户端和服务器都可以独立收缩,但偶尔的延迟是可以容忍的(例如在线纸牌游戏,许多MMO类游戏),然后使用 TCP长连接 吧。
- 如果客户端和服务器都可以独立收缩并且不能容忍延迟(例如大多数多人动作游戏,一些MMO课堂游戏),然后使用 UDP 吧。
这些也应该考虑在内:您的MMO客户端可以首先使用HTTP转到检索上次更新并使用UDP连接到游戏服务器。
永远不要害怕使用最好的工具来解决问题。
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除