计算机网络笔记:TCP协议 和UDP协议(传输层)
TCP 和 UDP都是传输层协议,他们都属于TCP/IP协议族。
TCP
基本概念
TCP的全称是传输控制协议
是一种面向连接的、可靠的、基于字节流
的传输层
通信协议。TCP 是面向连接的、可靠的流协议(流就是指不间断的数据结构)
TCP报文格式
TCP报文
是TCP层传输的数据单元,也称为报文段
,一个TCP报文段由首部
和数据段
两部分组成。其中,首部是TCP为了实现端到端可靠传输所加上的控制信息,而数据段部分则是由高层即应用层来的数据
源端口和目标端口
:分别写入源端口号和目的端口号,支持TCP的多路复用机制。发送序号
:为了确保数据传输的正确性,TCP对每一个传输的字节进行32位的按顺序编号,这个编号不一定从0开始,首部中的序号字段值指的是本报文段所发送的数据的第一个字节的编号。确认序号
:确认序号也称为接收序号,是期望收到对方下一个报文段的第一个数据字节的编号。首部长度
:占4位,表示TCP报文的首部长度(从图3-10中纵向上看,以32位为单位,表明在TCP报文首部中包含有5个32位的固定首部,即20字节的固定首部),由于4位二进制数表示的最大十进制数是15,因此数据偏移的最大值是(4字节×15)60字节,这也就是TCP首部的最大长度,即选项长度不能超过40字节。保留
:未用的6位,为将来的应用而保留,目前置为“0”。6个控制位
:完成TCP的主要传输控制功能(比如会话的建立和终止)。
窗口
:这个字段定义对方必须维持的窗口大小(以字节为单位)。注意,这个字段的长度是16位,这意味着窗口的最大长度是65 535字节。这个值通常称为接收窗口,它由接收方确定。此时,发送方必须服从接收端的支配。检验和
:这个16位的字段包含了校验和。TCP校验和的计算过程与前面描述的UDP的校验和所用的计算过程相同。但是,在UDP数据报中校验和是可选的,而对TCP来说,将校验和包含进去是强制的。紧急指针
:给出从当前顺序号到紧急数据位置的偏移量。选项
:提供一种增加额外设置的方法,长度可变,最长可达40字节,当没有使用该选项时,TCP的首部长度是20字节。填充
:当选项字段长度不足32位字长时,将会在TCP报头的尾部出现若干字节的全0填充。数据
:来自高层即应用层的协议数据。
特点
面向连接
面向连接,是指发送数据之前必须在两端建立连接。建立连接的方法是“三次握手”,这样能建立可靠的连接。建立连接,是为数据的可靠传输打下了基础。
仅支持单播传输
每条TCP传输连接只能有两个端点,只能进行点对点的数据传输,不支持多播和广播传输方式。
面向字节流
TCP不像UDP一样那样一个个报文独立地传输,而是在不保留报文边界的情况下以字节流方式进行传输。
可靠传输
对于可靠传输,判断丢包、误码靠的是TCP的段编号以及确认号。TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。
提供拥塞控制
当网络出现拥塞的时候,TCP能够减小向网络注入数据的速率和数量,缓解拥塞。
提供全双工通信
TCP允许通信双方的应用程序在任何时候都能发送数据,因为TCP连接的两端都设有缓存,用来临时存放双向通信的数据。当然,TCP可以立即发送一个数据段,也可以缓存一段时间以便一次发送更多的数据段(最大的数据段大小取决于MSS)
TCP的重传机制
由于TCP的下层网络(网络层)可能出现丢失、重复或失序的情况,TCP协议提供可靠数据传输服务。为保证数据传输的正确性,TCP会重传其认为已丢失(包括报文中的比特错误)的包。TCP使用两套独立的机制来完成重传,一是基于时间
,二是基于确认信息
。
TCP在发送一个数据之后,就开启一个定时器,若是在这个时间内没有收到发送数据的ACK确认报文,则对该报文进行重传,在达到一定次数还没有成功时放弃并发送一个复位信号。
TCP的拥塞控制机制
- 慢启动(慢开始)
在开始发送的时候设置cwnd = 1
(cwnd指的是拥塞窗口)
思路:开始的时候不要发送大量数据,而是先测试一下网络的拥塞程度,由小到大增加拥塞窗口的大小。为了防止cwnd增长过大引起网络拥塞,设置一个慢开始门限(ssthresh 状态变量) .
当cnwd < ssthresh
,使用慢开始算法
当cnwd = ssthresh
,既可使用慢开始算法,也可以使用拥塞避免算法
当cnwd > ssthresh
,使用拥塞避免算法
- 拥塞避免
拥塞避免未必能够完全避免拥塞,是说在拥塞避免阶段将拥塞窗口控制为按线性增长,使网络不容易出现阻塞。
思路: 让拥塞窗口cwnd缓慢的增大,即每经过一个返回时间RTT就把发送方的拥塞控制窗口加一。无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞,就把慢开始门限设置为出现拥塞时的发送窗口大小的一半。然后把拥塞窗口设置为1,执行慢开始算法。
- 快速重传
快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)。发送方只要连续收到三个重复确认就立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。
由于不需要等待设置的重传计时器到期,能尽早重传未被确认的报文段,能提高整个网络的吞吐量
- 快速恢复
当发送方连续收到三个重复确认时,就执行“乘法减小”
算法,把ssthresh门限
减半。但是接下去并不执行慢开始算法。
考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd
设置为ssthresh
的大小,然后执行拥塞避免算法。
TCP的流量控制机制
一般来说,
流量控制
就是为了让发送方发送数据的速度不要太快,要让接收方来得及接收。TCP采用大小可变的滑动窗口
进行流量控制,窗口大小的单位是字节
。这里说的窗口大小
其实就是每次传输的数据大小
。
窗口概念示意图
-
a
发送端要发送900字节长的数据,划分为9个100个字节长的报文段,对方确定的发送窗口为500字节。发送端只要收到了对方的确认,发送窗口就可前移。发送端的TCP要维护一个指针,每发送一个报文段,指针就向前移动一个报文段的距离。当指针移动到发送窗口的最右端(即窗口前沿)时就不能再发送报文段了。 -
b
发送端已发送了400字节的数据,但只收到对前200字节数据的确认,同时窗口大小不变,我们注意到,现在发送端还可发送500-200=300字节。 -
c
发送端收到了对方对前400字节数据的确认,但窗口减小到400字节,于是,发送端还可发送400字节的数据。
流量控制机制过程
-
当一个连接建立时,连接的每一端分配一个缓冲区来保存输入的数据,并将缓冲区的大小发送给另一端。
-
当数据到达时,接收方发送确认,其中包含了自己剩余的缓冲区大小。(剩余的缓冲区空间的大小被称为窗口,指出窗口大小的通知称为窗口通告 。接收方在发送的每一确认中都含有一个窗口通告。)
-
如果接收方应用程序读数据的速度能够与数据到达的速度一样快,接收方将在每一确认中发送一个正的窗口通告。
-
如果发送方操作的速度快于接收方,接收到的数据最终将充满接收方的缓冲区,导致接收方通告一个零窗口 。发送方收到一个零窗口通告时,必须停止发送,直到接收方重新通告一个正的窗口。
TCP的可靠传输机制
TCP 的可靠传输机制
是基于连续 ARQ 协议
和滑动窗口协议
的。
TCP 协议在发送方维持了一个发送窗口,发送窗口以前的报文段是已经发送并确认了的报文段,发送窗口中包含了已经发送但 未确认的报文段和允许发送但还未发送的报文段,发送窗口以后的报文段是缓存中还不允许发送的报文段。当发送方向接收方发 送报文时,会依次发送窗口内的所有报文段,并且设置一个定时器,这个定时器可以理解为是最早发送但未收到确认的报文段。 如果在定时器的时间内收到某一个报文段的确认回答,则滑动窗口,将窗口的首部向后滑动到确认报文段的后一个位置,此时如 果还有已发送但没有确认的报文段,则重新设置定时器,如果没有了则关闭定时器。如果定时器超时,则重新发送所有已经发送 但还未收到确认的报文段,并将超时的间隔设置为以前的两倍。当发送方收到接收方的三个冗余的确认应答后,这是一种指示, 说明该报文段以后的报文段很有可能发生丢失了,那么发送方会启用快速重传的机制,就是当前定时器结束前,发送所有的已发 送但确认的报文段。
接收方使用的是累计确认的机制,对于所有按序到达的报文段,接收方返回一个报文段的肯定回答。如果收到了一个乱序的报文 段,那么接方会直接丢弃,并返回一个最近的按序到达的报文段的肯定回答。使用累计确认保证了返回的确认号之前的报文段都 已经按序到达了,所以发送窗口可以移动到已确认报文段的后面。
发送窗口的大小是变化的,它是由接收窗口剩余大小和网络中拥塞程度来决定的,TCP 就是通过控制发送窗口的长度来控制报文 段的发送速率。
但是 TCP 协议并不完全和滑动窗口协议相同,因为许多的 TCP 实现会将失序的报文段给缓存起来,并且发生重传时,只会重 传一个报文段,因此 TCP 协议的可靠传输机制更像是窗口滑动协议和选择重传协议的一个混合体。
UDP
基本概念
UDP的全称是用户数据报协议
,在网络中它与TCP协议一样用于处理数据包,是一种无连接
的协议。在OSI模型中,在传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。
特点
面向无连接
首先 UDP 是不需要和 TCP一样在发送数据前进行三次握手建立连接的,想发数据就可以开始发送了。并且也只是数据报文的搬运工,不会对数据报文进行任何拆分和拼接操作。
具体来说就是:
在发送端,应用层将数据传递给传输层的 UDP 协议,UDP 只会给数据增加一个 UDP 头标识下是 UDP 协议,然后就传递给网络层了
在接收端,网络层将数据传递给传输层,UDP 只去除 IP 报文头就传递给应用层,不会任何拼接操作
有单播,多播,广播的功能
UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。
面向报文
发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文
不可靠性
首先不可靠性体现在无连接上,通信都不需要建立连接,想发就发,这样的情况肯定不可靠。
并且收到什么数据就传递什么数据,并且也不会备份数据,发送数据也不会关心对方是否已经正确接收到数据了。
再者网络环境时好时坏,但是 UDP 因为没有拥塞控制,一直会以恒定的速度发送数据。即使网络条件不好,也不会对发送速率进行调整。这样实现的弊端就是在网络条件不好的情况下可能会导致丢包,但是优点也很明显,在某些实时性要求高的场景(比如电话会议)就需要使用 UDP 而不是 TCP。
头部开销小,传输数据报文时是很高
UDP 头部包含了以下几个数据:
1、两个十六位的端口号,分别为源端口(可选字段)和目标端口
2、整个数据报文的长度
3、整个数据报文的检验和(IPv4 可选字段),该字段用于发现头部信息和数据中的错误
因此 UDP 的头部开销小,只有8字节,相比 TCP 的至少20字节要少得多,在传输数据报文时是很高效的。
TCP和UDP的使用场景
TCP应用场景
效率要求相对低,但对准确性要求相对高的场景。因为传输中需要对数据确认、重发、排序等操作,相比之下效率没有UDP高。
例如:文件传输(准确高要求高、但是速度可以相对慢)、接受邮件、远程登录。
UDP应用场景
效率要求相对高,对准确性要求相对低的场景。
例如:QQ聊天、在线视频、网络语音电话(即时通讯,速度要求高,但是出现偶尔断续不是太大问题,并且此处完全不可以使用重发机制)、广播通信(广播、多播)。
UDP协议为什么不可靠?
UDP在传输数据之前不需要先建立连接,远地主机的运输层在接收到UDP报文后,不需要确认,提供不可靠交付。总结就以下四点:
- 不保证消息交付:不确认,不重传,无超时
- 不保证交付顺序:不设置包序号,不重排,不会发生队首阻塞
- 不跟踪连接状态:不必建立连接或重启状态机
- 不进行拥塞控制:不内置客户端或网络反馈机制