由于TCP能够保证数据包的传递,因此可以被认为是“可靠的”,而UDP并不保证任何东西,数据包可能会丢失。在应用程序中使用UDP传输数据相对于TCP流传输有什么优势?在什么情况下UDP会是更好的选择,为什么?
我假设UDP更快,因为它没有创建和维护流的开销,但如果一些数据永远无法到达目的地,那么这个假设是否还有意义呢?
由于TCP能够保证数据包的传递,因此可以被认为是“可靠的”,而UDP并不保证任何东西,数据包可能会丢失。在应用程序中使用UDP传输数据相对于TCP流传输有什么优势?在什么情况下UDP会是更好的选择,为什么?
我假设UDP更快,因为它没有创建和维护流的开销,但如果一些数据永远无法到达目的地,那么这个假设是否还有意义呢?
这是我最喜欢的问题之一。UDP经常被误解。
在你想要快速向另一台服务器获取简单答案的情况下,UDP表现最佳。通常情况下,你希望答案能够在一个响应数据包中返回,并且你准备实现自己的可靠性协议或重新发送机制。DNS就是这种情况的完美描述。(当然,DNS也支持TCP模式。)
另一个情况是在传输那些可以因为新数据的到来而替换上一批数据/状态的数据时,比如天气数据、视频流、股票行情服务(不用于实际交易)或者游戏数据。
还有一种情况是在管理海量状态时,你想避免使用TCP,因为操作系统无法处理那么多的会话。这种情况在今天很少见。事实上,现在有用户态TCP堆栈可供使用,这样应用程序编写人员就可以更精细地控制所需的TCP状态资源。在2003年之前,UDP确实是唯一的选择。
最后一种情况是用于组播流量。UDP可以同时向多个主机进行组播,而TCP则无法实现这一点。
UDP的“不可靠性”只是一种形式,传输并非绝对保证。实际上,它们几乎总是能够传递。它们只是在超时后不被确认和重试。
TCP套接字协商和握手的开销非常大。真的非常大。UDP没有明显的开销。
最重要的是,你可以轻松地用一些可靠的交付握手来补充UDP,这比TCP的开销小得多。请阅读此文:http://en.wikipedia.org/wiki/Reliable_User_Datagram_Protocol
UDP在发布-订阅类型的应用中广泛用于广播信息。我IRC,TIBCO大量使用UDP来通知状态更改。
任何其他形式的单向“重要事件”或“日志记录”活动都可以使用UDP数据包很好地处理。你想发送通知而不构建整个套接字。你不期望各个侦听器的任何响应。
系统“心跳”或“我还活着”的消息也是一个不错的选择。错过一个不是危机。连续错过半打以上才是。
我从事的产品支持客户端和服务器之间UDP(IP)和TCP/IP通信,该产品最初使用IPX,15年前添加了IP支持,3或4年前添加了TCP/IP支持。瞎猜一下:UDP到TCP的代码比例可能约为80/20。这个产品是一个数据库服务器,因此可靠性至关重要。我们必须处理UDP带来的所有问题(数据包丢失、数据包重复、数据包顺序等),这些问题已经在其他答案中提到过。很少会有问题,但有时候确实会出现问题,因此必须加以处理。支持UDP的好处是我们能够根据自己的用途进行定制,并从中调整更多的性能。
每个网络都会不同,但UDP通信协议对于我们来说通常会快一些。怀疑论者将正确地质疑我们是否正确地实现了所有内容。另外,你还能从一个2位数的声望值得到什么呢?尽管如此,我刚刚出于好奇进行了一次测试。测试读取100万条记录(从某张表中选择*)。我将每个单独客户端请求返回的记录数设置为1、10和100(使用每种协议进行三次测试运行)。服务器距离我只有两个跳跃,而且连接的是100Mbit的局域网。在这个特定的测试中,数字似乎与其他人以前发现的一致(UDP在大多数情况下快约5%)。每种协议的总时间(以毫秒为单位)如下:
IP和TCP的总数据传输量大约相同。我们在UDP通信中有额外的开销,因为我们拥有一些与TCP/IP相同的东西(校验和、序列号等),这些在TCP/IP中是“免费”的。例如,Wireshark显示使用UDP请求下一个记录集的大小为80字节,而使用TCP为84字节。
这里已经有很多好的答案,但我想补充一个非常重要的因素和摘要。通过正确调整,UDP可以实现更高的吞吐量,因为它不使用拥塞控制。TCP中的拥塞控制是非常重要的。它控制连接的速率和吞吐量,以尝试估计连接的当前容量,从而最小化网络拥塞。即使在非常可靠的链路上发送数据包(例如在核心网络中),路由器有限的缓冲区也会填满其容量并丢弃数据包,TCP通过缺少接收确认来注意到此丢包情况,并将连接速度降至容量估计值以下。 TCP还采用了称为“慢启动”的方法,但吞吐量(实际上是“拥塞窗口”)会缓慢增加,直到数据包被丢弃,然后再降低并缓慢增加直到数据包再次被丢弃等。这会导致TCP吞吐量波动。当你下载一个大文件时,你可以清楚地看到这一点。
因为UDP不使用拥塞控制,所以它可以更快且延迟更小,因为它不会寻求将缓冲区最大化到丢包点,即UDP数据包在缓冲区中停留的时间更短,并且以更少的延迟更快地到达目的地。由于UDP不使用拥塞控制,而TCP使用拥塞控制,因此它可以从TCP中夺取容量,以满足UDP流量。
但是,UDP仍然会受到拥塞和数据包丢失的影响,因此您的应用程序必须准备好以某种方式处理这些问题,通常使用重传或纠错码。
结果是UDP可以:
总之,只要您还实现了适当的重传机制,UDP就可以用于与TCP相同类型的任何应用程序。UDP非常快,延迟较小,不受连接拥塞的影响,可以传输固定大小的数据报,并且可以用于多播。
UDP具有较少的开销,并且适用于像流式传输实时数据(例如音频或视频)或在数据丢失情况下仍然可以接受的任何情况。
我知道的关于这个问题最好的答案来自 user zAy0LfpBZLC8mAC 在 Hacker News 上。这个答案非常好,我会按原样引用它。
TCP 具有队列头阻塞,因为它保证完整和有序的传输,所以当数据包在传输过程中丢失时,它必须等待缺失数据包的重传。而 UDP 则会按照到达的顺序将数据包传递给应用程序,包括重复的数据包,并且没有任何保证数据包是否到达或者以哪种顺序到达(实质上只是 IP 加上端口号和 (可选) 负载校验和),但这对于如电话这样的应用程序来说是可以接受的。在这种情况下,丢失几毫秒的音频通常并不重要,而延迟非常令人厌烦,所以不需要重新传输,只需丢弃任何重复的数据包,将重排序的数据包排序到几百毫秒的抖动缓冲区中,并且如果数据包未及时或根本未出现,则会被简单地跳过,在支持编解码的情况下可能进行插值。视频流传输是使用UDP的完美例子。