TCP 与 UDP 的区别
TCP 与 UDP 的区别
TCP 与 UDP 的区别属于老生常谈的问题了,这里简单整理下。
1、TCP/IP 网络模型
TCP/IP 模型是一系列网络协议的总称,这些协议可以划分为四层,分别为应用层、传输层、网络层以及网络接口层(网络接口层也可细分为数据链路层、物理层)。
- 应用层:负责向用户提供应用程序,比如 HTTP、FTP、DNS、Telnet、SMTP等。
- 传输层:负责对报文进行分组和重组,以 TCP 或 UDP 协议格式封装报文。
- 网络层:负责路由及将报文发送到目的网络或主机。
- 网络接口层:负责封装及解封 IP 报文,发送和接受 ARP/RAPP 报文等。
下表是 TCP/IP 模型及对应的 OSI 七层模型的作用及常用协议归纳:
OSI 七层模型 | TCP/IP 模型 | 功能 | TCP/IP协议族 |
---|---|---|---|
应用层 | 应用层 | 为应用程序提供服务 | HTTP, FTP, DNS, Telnet, TFTP, SNMP, SMTP |
表示层 | 数据格式化,数据加密 | 没有协议 | |
会话层 | 建立、管理和维护会话 | 没有协议 | |
传输层 | 传输层 | 建立、管理和维护端对端的连接 | TCP, UDP |
网络层 | 网络层 | IP选址及路由选择 | IP, ICMP,RIP, OSPF, IGMP |
数据链路层 | 网络接口层 | 提供介质(帧)访问和链路管理 | SLIP, CSLIP, ARP, RARP, MTU |
物理层 | 以二进制数据形式在物理媒体上传输数据 | ISO2110, IEEE802 |
整个数据传输过程中,数据在发送端时经过各层时都要附加上相应层的协议头和协议尾(仅数据链路层需要封装协议尾)部分,也就是要对数据进行协议封装,以标识对应层所用的通信协议。接下来介绍TCP/IP 中有两个具有代表性的传输层协议,即 TCP 和 UDP。
2、UDP
2.1、UDP 特点
UDP 协议一般作为流媒体应用、语音交流、视频会议所使用的传输层协议,我们大家都知道的 DNS 协议底层也使用了 UDP 协议,这些应用或协议之所以选择 UDP 主要是因为以下这几点
- 速度快,采用 UDP 协议时,只要应用进程将数据传给 UDP,UDP 就会将此数据打包进 UDP 报文段并立刻传递给网络层,然后 TCP 有拥塞控制的功能,它会在发送前判断互联网的拥堵情况,如果互联网极度阻塞,那么就会抑制 TCP 的发送方。使用 UDP 的目的就是希望实时性。
- 无须建立连接,TCP 在数据传输之前需要经过三次握手的操作,而 UDP 则无须任何准备即可进行数据传输。因此 UDP 没有建立连接的时延。如果使用 TCP 和 UDP 来比喻开发人员:TCP 就是那种凡事都要设计好,没设计不会进行开发的工程师,需要把一切因素考虑在内后再开干!所以非常靠谱;而 UDP 就是那种上来直接干干干,接到项目需求马上就开干,也不管设计,也不管技术选型,就是干,这种开发人员非常不靠谱,但是适合快速迭代开发,因为可以马上上手!
- 无连接状态,TCP 需要在端系统中维护连接状态,连接状态包括接收和发送缓存、拥塞控制参数以及序号和确认号的参数,在 UDP 中没有这些参数,也没有发送缓存和接受缓存。因此,某些专门用于某种特定应用的服务器当应用程序运行在 UDP 上,一般能支持更多的活跃用户
- 分组首部开销小,每个 TCP 报文段都有 20 字节的首部开销,而 UDP 仅仅只有 8 字节的开销。
这里需要注意一点,并不是所有使用 UDP 协议的应用层都是
不可靠
的,应用程序可以自己实现可靠的数据传输,通过增加确认和重传机制。所以使用 UDP 协议最大的特点就是速度快。
2.2、UDP 结构
每个 UDP 报文分为 UDP 报头和 UDP 数据区两部分。报头由 4 个 16 位长(2 字节)字段组成,分别说明该报文的源端口、目的端口、报文长度和校验值。
源端口号(Source Port) :这个字段占据 UDP 报文头的前 16 位,通常包含发送数据报的应用程序所使用的 UDP 端口。接收端的应用程序利用这个字段的值作为发送响应的目的地址。这个字段是可选项,有时不会设置源端口号。没有源端口号就默认为 0 ,通常用于不需要返回消息的通信中。
目标端口号(Destination Port): 表示接收端端口,字段长为 16 位
长度(Length): 该字段占据 16 位,表示 UDP 数据报长度,包含 UDP 报文头和 UDP 数据长度。因为 UDP 报文头长度是 8 个字节,所以这个值最小为 8,最大长度为 65535 字节。
校验和(Checksum):UDP 使用校验和来保证数据安全性,UDP 的校验和也提供了差错检测功能,差错检测用于校验报文段从源到目标主机的过程中,数据的完整性是否发生了改变。发送方的 UDP 对报文段中的 16 比特字的和进行反码运算,求和时遇到的位溢出都会被忽略,
UDP 不可靠的原因是它虽然提供差错检测的功能,但是对于差错没有恢复能力更不会有重传机制。
3、TCP
3.1、TCP 特点
-
面向连接,是指发送数据之前必须在两端建立连接。建立连接的方法是“三次握手”,这样能建立可靠的连接。建立连接,是为数据的可靠传输打下了基础。关于“三次握手”TCP三次握手及四次挥手。
-
仅支持单播传输,每条TCP传输连接只能有两个端点,只能进行点对点的数据传输,不支持多播和广播传输方式。
-
面向字节流,TCP不像UDP一样那样一个个报文独立地传输,而是在不保留报文边界的情况下以字节流方式进行传输。
-
可靠传输,对于可靠传输,判断丢包,误码靠的是TCP的序号以及确认号。TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。
-
提供拥塞控制,当网络出现拥塞的时候,TCP能够减小向网络注入数据的速率和数量,缓解拥塞。
-
TCP提供全双工通信,TCP允许通信双方的应用程序在任何时候都能发送数据,因为TCP连接的两端都设有缓存,用来临时存放双向通信的数据。当然,TCP可以立即发送一个数据段,也可以缓存一段时间以便一次发送更多的数据段(最大的数据段大小取决于MSS)。
关于全双工通信:
单工通信:单工数据传输只支持数据在一个方向上传输;在同一时间只有一方能接受或发送信息,不能实现双向通信,比如广播、电视等。
双工通信是一种点对点系统,由两个或者多个在两个方向上相互通信的连接方或者设备组成。双工通信模型有两种:全双工(FDX)和半双工(HDX)
-
全双工:在全双工系统中,连接双方可以相互通信,一个最常见的例子就是电话通信。全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。
-
半双工:在半双工系统中,连接双方可以彼此通信,但不能同时通信,比如对讲机,只有把按钮按住的人才能够讲话,只有一个人讲完话后另外一个人才能讲话。
3.2、TCP结构
TCP 的报文段结构如下图所示:
TCP 报文段结构相比 UDP 报文结构多了很多内容。但是前两个 32 比特的字段是一样的。它们是 源端口号 和 目标端口号,我们知道,这两个字段是用于多路复用和多路分解的。另外,和 UDP 一样,TCP 也包含校验和(checksum field)
,除此之外,TCP 报文段首部还有下面这些
- 32 比特的序号字段(sequence number field) 和 32 比特确认号字段(acknowledgment number field) 。这些字段被 TCP 发送方和接收方用来实现可靠的数据传输。
- 4 比特的首部字段长度字段(header length field),这个字段指示了以 32 比特的字为单位的 TCP 首部长度。TCP 首部的长度是可变的,但是通常情况下,选项字段为空,所以 TCP 首部字段的长度是 20 字节。
- 16 比特的接收窗口字段(receive window field) ,这个字段用于流量控制。它用于指示接收方能够/愿意接受的字节数量
- 可变的选项字段(options field),这个字段用于发送方和接收方协商最大报文长度,也就是 MSS 时使用
- 6 比特的 标志字段(flag field), ACK 标志用于指示确认字段中的值是有效的,这个报文段包括一个对已被成功接收报文段的确认;RST、SYN、FIN 标志用于连接的建立和关闭;CWR 和 ECE 用于拥塞控制;PSH 标志用于表示立刻将数据交给上层处理;URG 标志用来表示数据中存在需要被上层处理的 紧急 数据。紧急数据最后一个字节由 16 比特的紧急数据指针字段(urgeent data pointer field) 指出。一般情况下,PSH 和 URG 并没有使用。
3.3、序号、确认号实现传输可靠性
TCP 报文段首部中两个最重要的字段就是 序号 和 确认号,这两个字段是 TCP 实现可靠性的基础,那么你肯定好奇如何实现可靠性呢?要了解这一点,首先我们得先知道这两个字段里面存了哪些内容吧?
一个报文段的序号就是数据流的字节编号 。因为 TCP 会把数据流分割成为一段一段的字节流,因为字节流本身是有序的,所以每一段的字节编号就是标示是哪一段的字节流。比如,主机 A 要给主机 B 发送一条数据。数据经过应用层产生后会有一串数据流,数据流会经过 TCP 分割,分割的依据就是 MSS,假设数据是 10000 字节,MSS 是 2000 字节,那么 TCP 就会把数据拆分成 0 - 1999 , 2000 - 3999 的段,依次类推。
所以,第一个数据 0 - 1999 的首字节编号就是 0 ,2000 - 3999 的首字节编号就是 2000 。。。。。。
然后,每个序号都会被填入 TCP 报文段首部的序号字段中。
至于确认号的话,会比序号要稍微麻烦一些。
TCP 是一种全双工的通信协议,因此主机 A 在向主机 B 发送消息的过程中,也在接受来自主机 B 的数据。主机 A 填充进报文段的确认号是期望从主机 B 收到的下一字节的序号。稍微有点绕,我们来举个例子看一下。比如主机 A 收到了来自主机 B 发送的编号为 0 - 999 字节的报文段,这个报文段会写入序号中,随后主机 A 期望能够从主机 B 收到 1000 - 剩下的报文段,因此,主机 A 发送到主机 B 的报文段中,它的确认号就是 1000 。
4、TCP和UDP的比较
以下是简单的比较:
UDP | TCP | |
---|---|---|
是否连接 | 无连接 | 面向连接 |
是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输,使用流量控制和拥塞控制 |
连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一通信 |
传输方式 | 面向报文 | 面向字节流 |
首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
适用场景 | 适用于实时应用(IP电话、视频会议、直播等) | 适用于要求可靠传输的应用,例如文件传输 |
参考资料: