首页 文章

Tcp可靠性与Udp负载对于认真,高性能的服务器

提问于
浏览
8

速度,优化和可扩展性是Udp和Tcp协议之间的典型比较 . Tcp吹嘘可靠性有一点额外开销的缺点,但速度很好,非常好 . 一旦Tcp套接字被实例化,保持套接字打开需要一些开销 . 但与Udp所描述的负担相比,哪种协议实际上有更多的开销?我也听说过Tcp存在可扩展性问题......但是互联网(网页/服务器)在Tcp上运行 - 那么Tcp是什么阻碍了可扩展性呢?

好的...所以Udp不需要保持连接打开的开销 . 但是,它要求您编写额外的方法以确保所有数据包都到达那里,希望按照您希望它接收的顺序 . 如果未完整收到数据包,则必须告知客户端或服务器重新发送 . 此外,您还必须为部分数据包保留某种消息收集,重建部分消息,并在最终处理消息之前检查完整的消息 . 更不用说如果消息的第二部分永远不会成功,你必须要么重新发送整个内容,要么重新发送我们缺少的部分,或者其他什么 .

基本上,我的问题是:

  • 为什么我会选择Udp over Tcp作为一个严肃的高性能服务器,添加了"overhead"的消息检查和手动ACK与连续流的"overhead"?

  • 如果Tcp足以满足魔兽世界的需求,为什么Tcp不被广泛接受作为游戏服务器使用的协议?

注意:我不反对为服务器实现Udp选项 . 我们在.Net 3.5框架上使用C# . 所以我也对处理Udp负担的最佳实践感兴趣 . 我也在套接字级别使用异步方法,而不是使用TcpListener,TcpClient等 .

5 回答

  • 4

    好吧,我建议再读一些 . 有很多地方可以查看TCP与UDP的专业版和内容,反之亦然,这里有几个:

    但是,这个链接可能对您最感兴趣,因为它直接与网络游戏编程有关:

    如果我引用一些小的东西:

    这个决定似乎很清楚,TCP做了我们想要的一切,而且它非常容易使用,而UDP是一个巨大的痛苦,我们必须从头开始编写所有内容 . 显然我们只是使用TCP吗?错误 . 使用TCP是开发网络游戏时可能犯的最大错误!要了解原因,您需要了解TCP在IP之上的实际操作,以使一切看起来如此简单!

    我仍然建议你自己研究这个问题,并确保在一天结束时哪些协议适合 your . 话虽如此,似乎大多数游戏都使用UDP作为数据 . 任何不断更新整个状态的东西都不需要保证数据包传输的开销 .

  • 11

    首先,我将从Unix Network Programming第22.4节"When to Use UDP instead of TCP"中解释史蒂文斯:

    他基本上说了以下几点:

    • UDP是广播/多播的唯一选项 - 因此您必须在那里使用它 .

    • UDP可用于简单的请求/回复应用程序 . 但你必须添加自己的错误检测意味着至少ack,超时和重新传输 .

    • UDP不应该用于批量数据传输(文件传输),因为您必须在TCP中构建所有功能才能使其正常工作 .

    • UDP应该用于实时数据,其中交付速度最重要,一些数据丢失不是问题,如实时传感器数据,实时多媒体流,实时股票报价等 .

    第一个问题的答案非常依赖于您对"high-performance"的定义 . 如果您主要担心的是低延迟,即尽可能快地到达UDP的各个数据包/请求将是最佳选择 . 这有两个主要原因 . 假设数据包/请求相互独立,而不是使用TCP会引入一个称为head-of-line blocking的问题 .

    假设您发送两个独立的数据包/请求 . 首先是A然后B.由于TCP是基于流的,如果A在网络中丢失并需要重新传输,那么即使B已经成功到达,它也无法通过堆栈直到A到达,引入不必要的延迟 . 不仅如此,但是在A到达之前,堆栈不能确认B,这可能导致B也被重传,从而导致不必要的网络拥塞 .

    解决此问题的一种方法是为每个请求使用单独的连接,但这也会引入延迟 and hogs系统资源 . UDP绕过所有这些问题 .

    高性能(低延迟)服务器中的另一个问题是Nagle Algorithm,这会在TCP通信中增加显着的延迟 .

    你的第二个问题的答案是WoW可能发送数据流,而不是独立的请求/回复对 . 此外,通过禁用Nagle algorithm可以删除TCP的某些延迟 . 如果他们确实使用了一些请求/回复通信,他们可能只是做出了一个设计决定,即可靠性比延迟更重要 .

  • 1

    定义“严重的高性能” - 您在谈论多少并发连接以及流动了多少数据?

    看一下这个问题的答案What do you use when you need reliable UDP?,其中列出了一些已经在UDP上构建的可靠协议 . 你可能会找到一个适合你情况的,或者你至少可以找到一些有用的想法 .

    这里有效使用UDP的关键是具有一定程度的可靠性和某种程度的不可靠性,并且您可以获得更多优势,每个数据报能够独立于其他数据报处理 . TCP的优势在于您可以对每个数据报采取行动,并决定是否可以在它到达时使用它 . 这就是它适用于动作游戏的原因 .

    所以,恕我直言,如果您需要100%的可靠性和订单交付,那么请使用TCP;不要尝试在UDP中重新实现TCP .

  • 1

    我认为TCP / IP中阻止可伸缩性的最大部分是它在所有传入/传出连接上维护一个缓冲区,基本上是窗口的大小 . 因此,如果我有一个高延迟但我正在谈论的高吞吐量客户端,我必须将所有发送的数据包保留在缓冲区中,直到我收到确认 . 因此,对于一些连接,这很好,但是对于处理100K连接,它可能开始成为问题的开销 . 在接收端,如果丢弃数据包,它将再次缓冲所有收到的新数据包,直到重新传输所需的数据包为止 .

    如果你要实现重传,你需要做同样的事情,因此会有相同的开销 . 但是,如果您知道端到端链路速度,或者某些消息可能无序传送,或某些消息不需要重新传输,UDP确实为您提供了优势 . 保持游戏场景:

    包1 =移到1,1包2 =射包3 =移到2,2

    大多数游戏设计师,如果数据包1丢失,但收到数据包3,则数据包1不再重要,因为它反正包含过时信息 . 但是,您可以选择说数据包2很重要,因此如果它没有被激活,则发送重传 .

    如果您需要高吞吐量,并且直接使用1000Mbps以太网连接两台服务器,TCP / IP将需要一段时间来扩展并产生额外的开销,并且由于拥塞避免机制,可能永远无法实现真正的千兆位连接 . 但是,你知道它是1 Gbps,所以你可以设置你自己的UDP传输速率高达1 Gbps(减去开销) .

    更直接地回答你的问题:如果你要打扰每个数据包,除了你可以在等待重传时处理一些消息(除非你想要按顺序交付)之外,拥有UDP并没有太大的好处 . 好) .

    Udp不被认为是游戏服务器,主要是出于上述情况,以及实时战斗系统,例如第一人称射击游戏,其中可以丢弃消息,并且即将发生的新消息将使丢弃的消息无效 . 魔兽世界可以使用TCP,因为它们不必像时间一样精确,并且可能有一些好的逻辑,这使得你更难以分辨出差异 . 战斗系统根本不需要速度 .

    我还认为,一些理由是多年前保留的,当时每个人的互联网连接都不太可靠,而且速度较慢 . TCP对于共享网络也更宽松,因此如果有很多事情发生,它将会减速,因此每个人都可以分享连接(避免拥塞) .

    TCP / IP是一项由多年研究中比我聪明得多的人设计的协议 . 过去几年的调整使它能够发挥作用我们看到的平均网络速度越来越快,越来越好,并且不需要很好的理解使用 .

    但是,用UDP代替它,确实需要对网络有重要的了解 . 我已经看到写得很糟糕的UDP程序使1Gbps链路饱和并终止链路上的所有流量,因为它们实现了一种相当天真的重传算法 .

    这里的东西TCP列表/ IP现在可以做到这一点,你会松动前往UDP: - 为了到达你的程序 - 重传(现在用快速重发,选择性确认,和其他功能) - 最大段大小 - 路径MTU发现 - 黑洞检测(路径MTU的扩展) - 拥塞避免

    因此,如果适合您的需要,我强烈建议坚持使用TCP / IP .

    也不是为了挑选,但你评论在TCP / IP上运行的互联网是错误的,实际上有几十个互联网可路由协议check them out here . 我认为你指的是网页和网络服务器都在TCP / IP之上运行 . 对于网络而言,我们人类在网络上赢得了足够的积极性,这也很棒:Google thinks tcp/ip should be more aggressive by default

  • 7

    它的可靠性与性能 .

    FPS游戏不需要 - 所有数据包到达目的地,按顺序到达,特别大,或确保大吞吐量 . 它们只要求数据包尽可能地到达服务器 . 这是最终的优先级,TCP的开销只是一个不必要的负担 .

    魔兽,在其“不太实时”通信和经常吨数据的发送(在拥挤的区域),可能不得不应付超过MTU的分组(要求分段),并且需要可靠性(更少的更大的数据包=丢包伤害更大) . 因此,它对TCP的选择是合乎逻辑的 . 对于大多数回合制战略游戏等也是如此 . 在30分钟ping播放器的玩家用ping 50ms击败玩家的UDP是国王 .

相关问题