也来聊一聊TCP和UDP

TCP和UDP有多重要

今天的大多数人都和我一样,生活和学习都离不开网络了。从早到晚要刷N多次空间和朋友圈、新闻,看NBA,登录视频网站看个电影或者放首歌嗨嗨,上这个东那个猫购个物淘个宝什么的,遇到问题连想都懒得想就急着去问google或百度。不过,一般情况下都不太了解是什么东西支撑起了我们丰富多彩的网络生活。既然自身是个程序员,就不能不深入了解一下背后的真相了。本文主要聊一聊传输层的两个协议TCP和UDP,三个原因:

  • 这两个协议如此重要,因为应用层绝大多数的程序要么选择TCP要么选择UDP来传输数据;
  • 同样是传输层的协议,但TCP和UDP有很大的差别,我们必须弄清它们各自的特点和工作方式;
  • 我们常常听到的就是“TCP/IP”,而UDP常常被忽视,UDP不重要么?

先来看看TCP和UDP到底有多重要。

我们要访问某个网站的时候,在浏览器中输入网址http://www.xxx.com,这个一串字符首先要被解释成该网站服务器对应的IP浏览器才能访问到,从域名到IP地址的解析需要靠DNS这项服务来完成,浏览器和DNS之间就采用了UDP来传输数据(DNS也采用TCP);当浏览器取得IP地址后,向服务器发起请求和接收服务器的数据,这之间的过程采用了HTTP协议,HTTP协议就是靠TCP来实现的。

这是一个最简单的例子,说明TCP和UDP的重要性。事实上,TCP不仅用在浏览器和www服务器之间,我们收发邮件使用的SMTP和POP3协议、用于文件传输的FTP协议、用于加密安全登陆的SSH协议等等。UDP除了应用在DNS,什么简单网络管理协议SNMP、动态主机配置协议DHCP、路由信息协议RIP都用到了它。


TCP和UDP背景和历史

计算机领域聪明的头脑多,搞出来的东西也多,很多技术可能搞出来没过几年就被淘汰了。然而TCP/TP却经历考验发展到今天,这个最初由于军事目的从美国国防部走出来的老古董,已经服役了二三十年。我觉得了解一下它的背景和历史是很有必要的。

我简单转述一下一个网页上的话:

TCP/IP最早源于1969年,美国国防部的ARPANET,其目的是要为位于美国许多区域的超级计算机之间提供高速的网络通信连接。早期有Telnet和FTP协议被开发出来,成为通过ARPANET共享信息的指定工具。随着ARPANET规模越来越大,出现了另外两种重要的协议:

  • 1974年,有了TCP草案,它描述了在网络上如何建立一个可靠的、主机到主机的数据传输服务。
  • 1981年,有了IP草案,它描述了如何实现相互连接的网络之间的寻址标准和路由数据包。

我们可以看到,现在的TCP/IP协议族中,IP是TCP的底层,但是它的实现要比TCP晚几年。这是为什么呢?

事实上,刚开始的时候这有一个核心的协议,TCP。1974年写进RFC675的是这个协议的version 1,那时候“TCP”这个所写还是“Transmission Control Program”。1977年的时候,搞出来了TCP的version 2。但是一位非常重要的先驱 Jon Postel 这个版本的指出了当时设计的协议的两个问题:

We are screwing up in our design of internet protocols by violating the principle of layering. Specifically we are trying to use TCP to do two things: serve as a host level end to end protocol, and to serve as an internet packaging and routing protocol. These two things should be provided in a layered and modular way. I suggest that a new distinct internetwork protocol is needed, and that TCP be used strictly as a host level end to end protocol.

Jon Postel的这段话促成了IP协议的诞生,将原来的TCP切分成现在我们熟悉的传输层的TCP和网络层的IP协议。1978年的时候,这个切分后的TCP和IP成为version 3。直到1980年,正式的TCP和IP协议的版本才被应用到网络中,这就是我们习惯的TCP/IPv4,整个协议的version 4。随后的1980s到越来越多的网络使用TCP/IP连接到ARPAnet最后形成了Internet。

“委屈”的UDP

和TCP比起来,作为数据传输的另一种协议UDP显得“委屈”了些,它的光环基本被TCP盖过。我们用“TCP/IP”代表了整个TCP/IP协议族。事实上,UDP本身填补了TCP/IP协议族中一个重要的位置。因为尽管TCP被设计成为一种有连接的、可靠的、流量控制以及拥塞避免的协议,这些所有的初衷都是为了保证数据在网络中有效地、正确地从一个主机到达另一个主机,但是后来人们发现把这所有的功能都弄在一起也许是个错误,有些程序并不需要这种可靠性的保证,使用TCP反而无法表现出最好的性能。

许多应用程序想在传输层有一个可替代TCP的协议,不需要TCP那些特性,于是UDP诞生了。UDP最重要的两个特性就是“simple and fast”。如果你看一下TCP和UDP包头的结构和大小,你就会发现UDP确实非常简单!在抛弃了TCP那些繁琐的东西之后,UDP只负责快速地将数据打包传递给底下的IP层,把可靠性保证和重传这种事情交给应用程序来处理,这就是它快的原因。


为什么TCP巨复杂

一个“伟大而牛逼的协议”应该是怎样的?看了酷壳的TCP 的那些事儿(上)、TCP 的那些事儿(下)这两篇文章,对TCP这个协议有了更好的理解,告诉了我们TCP为什么被设计得这么复杂。因为,TCP本身要解决的问题相当复杂。

TCP/IP协议栈是按照分层模型设计出来的,分层的好处让每一层的协议只做这一层“该做”的事情,这样子就能把事情变得简单一点(前面说了IP就是从最初的TCP中分离出来的)。IP协议已经完成了很重要的两项功能:寻址和路由,TCP要完成的重要使命,就是在网络上的主机与主机(端到端)之间把数据可靠、准确地传递过去。从“TCP”的含义上来看,它就是要完成“传输控制”,它要解决以下问题:

  • 要维持主机到主机之间“有连接”,双方都要有“状态”(TCP Flag)
  • 要保证数据包按照顺序到达,要解决乱序问题(Sequence Number)
  • 要保证数据包都会安全到达,要解决重传问题(Acknowledgement Number)
  • 要保证双方的数据能够处理得过来,要解决流量控制问题(Advertised-Window)
  • 要掌握的整体状况,保证网络不拥堵,搞了一大堆算法来做拥塞控制(Congestion Handling)

可见,正是这些复杂的问题让TCP想简单点都不行。

关于TCP协议为什么搞得这么复杂,建议再去阅读一下CSDN上的这篇博客。


TCP和UDP的特点

从前面的讨论中可以看到,虽然TCP和UDP都是在IP协议之上实现的,但是却有着非常大的差异。TCP基本上把数据包在复杂网络中传输的相关问题都搞定了,以巨大的complexities换取了reliability,让上层的应用程序像读写文件一样接收和发送网络上的数据。而UDP呢,倒是和IP有点像,只负责把数据发出去,能否到达不知道,丢包重传、流量控制都需要应用程序自己去做。

TCP是一个基于字节流(byte stream)的协议,而且为了提高带宽利用率引入了Nagle’s Algorithm,一个TCP连接的发送端和接收端都有接收缓冲区和发送缓冲区,TCP会将应用程序要send的数据先暂存起来,存够了再封装到IP数据包里面或者通知应用程序接收。UDP虽然不提供TCP那样的可靠性,但是它至少保证了一点,如果发送了一个UDP包,那么要么这个包完全到达接收端再通知接收端的应用程序读取,要么就不会到达。

Glenn写的一篇文章总结了TCP和UDP各自的特点:

TCP:

  • 有连接的
  • 可靠性和顺序保证
  • 自动将你的数据分成Packets(IP层的数据包)
  • 确保数据在网络中不会发送的太快 (流量控制)
  • 容易使用,像读写文件一样

UDP:

  • 没有连接的概念,需要自己主机到主机的维护
  • 没有可靠性和按序到达的保证,数据包到达时可能乱序、重复,也可能完全丢失
  • 需要自己切分成合适的Packets(add:UDP包有大小限制,控制在548字节以内,大了有丢包风险)
  • 需要自己在程序逻辑中确保发包速度不能太快(add:发包频率一定要控制,速度开也增大丢包风险)
  • 需要自己在程序逻辑中实现丢包重传

有关TCP和UDP的比较,还有一篇文章列举得很详细:TCP vs. UDP


如何根据你的项目来选择网络协议?特别是游戏服务器?

参考:帖子1、 知乎讨论、Stackoverflow讨论、 Game servers: UDP vs TCP

UDP:

UDP is typically used for applications such as streaming media (audio, video, Voice over IP etc.) where on-time arrival is more important than reliability, or for simple query/response applications like DNS lookups, where the overhead of setting up a reliable connection is disproportionately large. Real-time Transport Protocol (RTP) is a datagram protocol that is designed for real-time data such as streaming audio and video.

一般来说,选择什么样的协议应该是系统设计人员考虑的问题。

游戏服务器开发选择哪种协议,是基于什么样的考虑?

HTTP?

This is one of my favorite questions. UDP is so misunderstood.

In situations where your really want to get a simple answer to another server quickly, UDP works best. In general, you want the answer to be in one response packet, and you are prepared to implement your own protocol for reliability or resends. DNS is the perfect description of this use case. The costs of connection setups are way to high (yet, DNS does support a TCP mode as well).

Another case is when you are delivering data that can be lost because newer data coming in will replace that previous data/state. Weather data, video streaming, a stock quotation service (not used for actual trading), or gaming data come to mind.

Another case is when you are managing a tremendous amount of state and you want to avoid using TCP because the OS cannot handle that many sessions. This is a rare case today. In fact, there are now user-land TCP stacks that can be used so that the application writer may have finer grained control over the resources needed for that TCP state. Prior to 2003, UDP was really the only game in town.

One other case is for multicast traffic. UDP can be multicasted to multiple hosts whereas TCP cannot do this at all.

问题集中在:

  1. 效率
  2. 可靠性
  3. 资源消耗
  4. 数据包大小(理解TCP为什么是“byte stream”,UDP为什么是“user datagram”)
  5. 最大连接数
  6. 编程开发的难易
  7. 延迟对程序的影响
  8. 多播?组播?广播?

参考资料

  1. http://en.wikipedia.org/wiki/Transmission_Control_Protocol
  2. http://en.wikipedia.org/wiki/User_Datagram_Protocol
  3. http://en.wikipedia.org/wiki/Internet_protocol_suite
  4. http://www.tcpipguide.com/free/t_TCPIPOverviewandHistory.htm
  5. http://www.tcpipguide.com/free/t_UDPOverviewHistoryandStandards.htm
  6. http://technet.microsoft.com/en-us/library/cc775383(v=ws.10).aspx
  7. http://coolshell.cn/articles/11564.html
  8. http://coolshell.cn/articles/11609.html
  9. http://1024monkeys.wordpress.com/2014/04/01/game-servers-udp-vs-tcp/
  10. http://gafferongames.com/networking-for-game-programmers/udp-vs-tcp/
  11. http://www.diffen.com/difference/TCP_vs_UDP
  12. http://stackoverflow.com/questions/5970383/difference-between-tcp-and-udp
  13. http://stackoverflow.com/questions/1099672/when-is-it-appropriate-to-use-udp-instead-of-tcp
  14. http://blog.csdn.net/dog250/article/details/6612496

你可能感兴趣的:(Linux,网络,协议)