因为TCP保证数据包的传递,因此可以被认为是“可靠的”,而UDP不保证任何东西,数据包可能会丢失。在应用程序中使用UDP而不是TCP流传输数据的优势是什么?在什么情况下UDP是更好的选择,为什么?
我假设UDP更快,因为它没有创建和维护流的开销,但如果一些数据从未到达目的地,这不是无关紧要的吗?
因为TCP保证数据包的传递,因此可以被认为是“可靠的”,而UDP不保证任何东西,数据包可能会丢失。在应用程序中使用UDP而不是TCP流传输数据的优势是什么?在什么情况下UDP是更好的选择,为什么?
我假设UDP更快,因为它没有创建和维护流的开销,但如果一些数据从未到达目的地,这不是无关紧要的吗?
当前回答
关于这个问题,我所知道的最好的答案之一来自Hacker News的用户zAy0LfpBZLC8mAC。这个答案太好了,我就原原本本地引用它吧。
TCP has head-of-queue blocking, as it guarantees complete and in-order delivery, so when a packet gets lost in transit, it has to wait for a retransmit of the missing packet, whereas UDP delivers packets to the application as they arrive, including duplicates and without any guarantee that a packet arrives at all or which order they arrive (it really is essentially IP with port numbers and an (optional) payload checksum added), but that is fine for telephony, for example, where it usually simply doesn't matter when a few milliseconds of audio are missing, but delay is very annoying, so you don't bother with retransmits, you just drop any duplicates, sort reordered packets into the right order for a few hundred milliseconds of jitter buffer, and if packets don't show up in time or at all, they are simply skipped, possible interpolated where supported by the codec. Also, a major part of TCP is flow control, to make sure you get as much througput as possible, but without overloading the network (which is kinda redundant, as an overloaded network will drop your packets, which means you'd have to do retransmits, which hurts throughput), UDP doesn't have any of that - which makes sense for applications like telephony, as telephony with a given codec needs a certain amount of bandwidth, you can not "slow it down", and additional bandwidth also doesn't make the call go faster. In addition to realtime/low latency applications, UDP makes sense for really small transactions, such as DNS lookups, simply because it doesn't have the TCP connection establishment and teardown overhead, both in terms of latency and in terms of bandwidth use. If your request is smaller than a typical MTU and the repsonse probably is, too, you can be done in one roundtrip, with no need to keep any state at the server, and flow control als ordering and all that probably isn't particularly useful for such uses either. And then, you can use UDP to build your own TCP replacements, of course, but it's probably not a good idea without some deep understanding of network dynamics, modern TCP algorithms are pretty sophisticated. Also, I guess it should be mentioned that there is more than UDP and TCP, such as SCTP and DCCP. The only problem currently is that the (IPv4) internet is full of NAT gateways which make it impossible to use protocols other than UDP and TCP in end-user applications.
其他回答
视频流是使用UDP的一个很好的例子。
We have web service that has thousands of winforms client in as many PCs. The PCs have no connection with DB backend, all access is via the web service. So we decided to develop a central logging server that listens on a UDP port and all the clients sends an xml error log packet (using log4net UDP appender) that gets dumped to a DB table upon received. Since we don't really care if a few error logs are missed and with thousands of client it is fast with a dedicated logging service not loading the main web service.
UDP确实有更少的开销,适合做一些事情,比如流式实时数据,如音频或视频,或者在任何情况下,如果数据丢失是ok的。
There are already many good answers here, but I would like to add one very important factor as well as a summary. UDP can achieve a much higher throughput with the correct tuning because it does not employ congestion control. Congestion control in TCP is very very important. It controls the rate and throughput of the connection in order to minimize network congestion by trying to estimate the current capacity of the connection. Even when packets are sent over very reliable links, such as in the core network, routers have limited size buffers. These buffers fill up to their capacity and packets are then dropped, and TCP notices this drop through the lack of a received acknowledgement, thereby throttling the speed of the connection to the estimation of the capacity. TCP also employs something called slow start, but the throughput (actually the congestion window) is slowly increased until packets are dropped, and is then lowered and slowly increased again until packets are dropped etc. This causes the TCP throughput to fluctuate. You can see this clearly when you download a large file.
因为UDP没有使用拥塞控制,它可以更快,并且经历更少的延迟,因为它不会寻求最大化缓冲区直到丢弃点,也就是说,UDP数据包在缓冲区中花费的时间更少,到达那里的速度更快,延迟更少。由于UDP不采用拥塞控制,但TCP采用拥塞控制,因此它可以从TCP中占用生成UDP流的容量。
UDP仍然容易受到拥塞和数据包丢失的影响,所以你的应用程序必须准备好以某种方式处理这些问题,可能使用重传或错误纠正代码。
结果是UDP可以:
Achieve higher throughput than TCP as long as the network drop rate is within limits that the application can handle. Deliver packets faster than TCP with less delay. Setup connections faster as there are no initial handshake to setup the connection Transmit multicast packets, whereas TCP have to use multiple connections. Transmit fixed size packets, whereas TCP transmit data in segments. If you transfer a UDP packet of 300 Bytes, you will receive 300 Bytes at the other end. With TCP, you may feed the sending socket 300 Bytes, but the receiver only reads 100 Bytes, and you have to figure out somehow that there are 200 more Bytes on the way. This is important if your application transmit fixed size messages, rather than a stream of bytes.
总之,UDP可以用于TCP可以使用的任何类型的应用程序,只要您还实现了适当的重传输机制。UDP可以非常快,有更少的延迟,在连接的基础上不受拥塞的影响,传输固定大小的数据报,并可用于组播。
UDP can be used when an app cares more about "real-time" data instead of exact data replication. For example, VOIP can use UDP and the app will worry about re-ordering packets, but in the end VOIP doesn't need every single packet, but more importantly needs a continuous flow of many of them. Maybe you here a "glitch" in the voice quality, but the main purpose is that you get the message and not that it is recreated perfectly on the other side. UDP is also used in situations where the expense of creating a connection and syncing with TCP outweighs the payload. DNS queries are a perfect example. One packet out, one packet back, per query. If using TCP this would be much more intensive. If you dont' get the DNS response back, you just retry.