Chapter 5. 传输层
公式与性质
-
复用和分用
- 复用:发送方不同的应用进程都可以使用同一个传输层协议传送数据。
- 分用:接收方的传输层在剥去报文的首部后能够把这些数据正确交付到目的应用进程。
-
差错检测
- 传输层要对收到的报文(首部和数据部分)进行差错检测。对于
TCP
协议,若接收方发现报文段出错,则要求发送方重发该报文段。对于UDP
协议,若接收方发现数据报出错,则直接丢弃。
在网络层,
IP
数据报首部中的检验和字段只检验首部是否出错,而不检查数据部分。 - 传输层要对收到的报文(首部和数据部分)进行差错检测。对于
-
端口号
TCP
、UDP
的端口号是互相独立的。- 服务器端使用的端口号
- 熟知端口号
0 ~ 1023
应用程序 端口号 FTP
21 TELNET
23 SMTP
25 DNS
53 TFTP
69 HTTP
80 SNMP
161 - 登记端口号
1024 ~ 49151
- 熟知端口号
- 客户端使用的端口号
- 短暂端口号
49152 ~ 65535
- 短暂端口号
-
无连接服务与面向连接服务
TCP
提供面向连接的可靠服务,通信双方在传送数据之前必须先建立连接,然后基于此连接进行可靠数据传输,数据传输结束后要释放连接。UDP
提供无连接的不可靠服务,通信双方在传送数据之前不需要建立连接,接收方的传输层在收到UDP
用户数据报后,无须给发送方发回任何确认。- 在网络层若采用虚电路方式,则无法提供无连接服务;而传输层采用
TCP
不影响网络层提供无连接服务。
-
UDP
- 特点
- 无须建立连接。因此不会引入建立连接的时延。
- 无连接状态。
- 首部开销小。
TCP
有 20B 的首部开销, 而UDP
仅有 8B 的开销。 - 没有拥塞控制, 因此网络中的拥塞不会影响源主机的发送速率。
- 支持一对一、一对多、多对一和多对多的交互通信。
- 不保证可靠交付,所有维护可靠性的工作可由用户在应用层来完成。
UDP
是面向报文的。报文不可分割,是UDP
数据报处理的最小单位。
- 首部格式
- 首部一共 8B ,由四个字段组成,每个字段 2B。
- 源端口号
- 目的端口号
- 长度(包括首部和数据)
最小值为 8,理论最大值 65535,实际最大值 65515 (
IP
数据报首部 20B)- 检验和
不想计算检验和时, 则直接令该字段为全 0。
- 检验
- 在计算检验和时,要在
UDP
数据报之前增加 12B 的伪首部(一般由源IP
,目的IP
,协议类型,UDP
长度等组成),伪首部并不是UDP
的真正首部。只是在计算检验和时,临时添加在UDP
数据报的前面,得到一个临时的UDP
数据报。检验和就是按照这个临时的UDP
数据报来计算的。伪首部既不向下传送又不向上递交,而只是为了计算检验和。
IP
数据报的检验和只检验IP
数据报的首部,但UDP
的检验和要将首部和数据部分一起检验。- 发送方首先把全 0 放入检验和字段并添加伪首部,然后把
UDP
数据报视为许多 16 位的字串接起来。若UDP
数据报的数据部分不是偶数个字节,则要在末尾填入一个全 0 字节(但此字节不发送)。然后按二进制反码计算出这些 16 位字的和(相当于普通加法中最高位进位需要回卷),将此和的二进制反码写入检验和字段,并发送。接收方把收到的UDP
数据报加上伪首部(若不为偶数个字节,则还需要补上全 0 字节)后, 按二进制反码求这些 16 位字的和。当无差错时其结果应为全 1,否则就表明有差错出现, 接收方就应该丢弃这个UDP数据报。
- 在计算检验和时,要在
- 特点
-
TCP
- 特点
- 是面向连接的传输层协议,是一条逻辑连接。
- 一条连接只能有两个端点,每一条连接只能是一对一的。
- 提供可靠交付的服务,保证传送的数据无差错、不丢失、不重复且有序。
- 提供全双工通信,允许通信双方的应用进程在任何时候都能发送数据,为此连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。
- 是而向字节流的,虽然应用程序和
TCP
的交互是一次一个数据块(大小不等),但TCP
把应用程序交下来的数据仅视为一连串的无结构的字节流。
UDP
报文的长度由发送应用进程决定,而TCP
报文的长度则根据接收方给出的窗口值和当前网络拥塞程度来决定。若应用进程传送到TCP
缓存的数据块太长,则TCP
就把它划分得短一些再传送;若太短, 则TCP
也可等到积累足够多的字节后再构成报文段发送出去。 - 首部格式
- 首部长度为 20B \sim 60B,且为 4B 的整数倍。
- 源端口号和目的端口号,各占 2B。
- 序号
seq
。占 4B,TCP
连接中传送的字节流中的每个字节都要按顺序编号,序号字段值指的是本报文段所发送的数据的第一个字节的序号。
例如,一报文段的序号字段值是 301,而携带的数据共有 100B, 表明本报文段的数据的最后一个字节的序号是 400 , 因此下一个报文段的数据序号应从 401 开始。
- 确认号
ack(ack_seq)
。占 4B , 是期望收到对方下一个报文段的第一个数据字节的序号。若确认号为 N , 则表明到序号 N-1 为止的所有数据都已正确收到。 - 数据偏移(即首部长度)。占 4bit,这里不是
IP
数据报分片的那个数据偏移,而是表示首部长度(首部中还有长度不确定的选项字段),它指出TCP
报文段的数据起始处距离TCP
报文段的起始处有多远。单位是 4B 。 - 保留。占 6bit ,保留为今后使用,目前应置为 0。
- 紧急位
urgent, URG
。 当URG = 1
时, 表明紧急指针字段有效。它告诉系统此报文段中有紧急数据, 应尽快传送。紧急数据被插入到报文段数据的最前面,而在紧急数据后面的数据仍是普通数据,因此要与首部中的紧急指针字段配合使用。 - 确认位
ACK
。 仅当ACK = 1
时确认号字段才有效。在连接建立后所有传送的报文段都必须把ACK
置 1 。只有第一次握手时ACK = 0
。 - 推送位
push, PSH
。两个应用进程进行交互式通信时,都希望在键入一个命令后立即就能收到对方的响应,此时发送方TCP
把PSH
置 1 ,接收方TCP
收到PSH = 1
的报文段后,就尽快交付给接收应用进程,而不再等到整个缓存都填满后再向上交付。 - 复位位
reset, RST
。当RST = 1
时,表示TCP
连接中出现严重差错(如主机崩溃等), 必须释放连接,然后重新建立传输连接。此外,它还可用于拒绝一个非法的报文段。 - 同步位
SYN
。当SYN = 1
时表示这是一个连接请求或连接接受报文。当SYN = 1, ACK = 0
时,表明这是一个连接请求报文,若对方同意建立连接,则应在响应报文中使用SYN = 1, ACK = 1
。只有第一次握手和第二次握手时SYN = 1
。 - 终止位
finish, FIN
。用来释放一个连接。当FIN = 1
时,表明此报文段的发送方的数据已发送完毕,并要求释放传输连接。只有第一次挥手和第三次挥手时FIN = 1
。 - 窗口
receive window, rwnd, rcvwnd
。占 2B 。窗口值告诉对方,从本报文段首部中的确认号算起,接收方目前允许对方发送的数据蜇(以字节为单位)。接收方的数据缓存空间是有限的,因此窗门值作为接收方让发送方设仅其发送窗口的依据。
例如, 设确认号是 701, 窗口字段是 1000。这表明,从 701 号算起,发送此报文段的一方还有接收 1000 字节数据(字节序号为 701 \sim 1700)的接收缓存空间。
- 检验和。占 2B。检验和字段检验的范围包括首部和数据两部分。在计算检验和时,和
UDP
一样,要在TCP
报文段的前面加上 12B 的伪首部(只需将UDP
伪首部的协议字段的 17 改成 6 ,UDP
长度字段改成TCP
长度,其他的和UDP
一样)。 - 紧急指针。占 2B。紧急指针仅在
URG = 1
时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据在报文段数据的最前面)。也就是说,使窗口为零也可以发送紧急数据。
紧急数据的序号独立。
- 选项。长度可变,最长可达 40B。当不使用选项时,
TCP
首部长度是 20B。TCP
最初只规定了一种选项即最大报文段长度Maximum Segment Size, MSS
。MSS
是TCP
报文段中的数据字段的最大长度。 - 填充。这是为了使整个首部长度是 4B 的整数倍。
- 连接的建立
- 客户机的
TCP
首先向服务器的TCP
发送连接请求报文段。这个报文段的首部中的同步位SYN = 1
,同时选择一个初始序号 seq=x (C -> S
的起始序号)。TCP
规定,SYN
报文段不能携带数据,但要消耗掉一个序号。这时,客户机进入SYN-SENT
(同步已发送)状态。 - 服务器的
TCP
收到连接请求报文段后,如同意建立连接,则向客户机发回确认,并为该TCP
连接分配缓存和变量。在确认报文段中,把SYN
位和ACK
位都置 1 ,确认号是 ack=x+1, 同时也为自己选择一个初始序号 seq=y (S -> C
的起始序号)。SYN
报文段不能携带数据,但要消耗掉一个序号。 这时,服务器进入SYN-RCVD
(同步收到)状态。 - 当客户机收到确认报文段后,还要向服务器给出确认,并为该
TCP
连接分配缓存和变量。确认报文段的ACK
位置 1 , 确认号 ack=y+1, 序号 seq=x+1。该报文段可以携带数据,若不携带数据则不消耗序号。这时,客户机进入ESTABLISHED
(已建立连接)状态。 - 当服务器收到来自客户机的确认后, 也进入
ESTABLISHED
状态。
- 客户机的
- 连接的释放
- 参与
TCP
连接的两个进程中的任何一个都能终止该连接。
- (可以但通常不携带数据)客户机打算关闭连接时,向其
TCP
发送连接释放报文段,并停止发送数据,主动关闭TCP
连接,该报文段的终止位FIN
置 1,序号 seq=u, 它等于前面已传送过的数据的最后一个字节的序号加 1,FIN
报文段即使不携带数据,也要消耗掉一个序号。这时,客户机进入FIN-WAIT-1
(终止等待 1)状态。TCP
是全双工的,即可以想象为一条TCP
连接上有两条数据通路,发送FIN
的一端不能再发送数据,即关闭了其中一条数据通路。但对方还可以发送数据。 - (可以携带数据)服务器收到连接释放报文段后即发出确认,确认号 ack=u+1, 序号 seq=v , 等于它前面已传送过的数据的最后一个字节的序号加 1 。然后服务器进入
CLOSE-WAIT
(关闭等待)状态。此时,从客户机到服务器这个方向的连接就释放了,TCP
连接处于半关闭状态。但服务器若发送数据,客户机仍要接收,即从服务器到客户机这个方向的连接并未关闭。客户机收到来自服务器的确认后,进入FIN-WAIT-2
(终止等待 2)状态,等待服务器发出的连接释放报文段。 - (可以但通常不携带数据)若服务器已经没有要向客户机发送的数据,就通知
TCP
释放连接,此时,其发出FIN = 1
的连接释放报文段。设该报文段的序号为 w (处于半关闭状态的服务器可能又发送了一些数据),还必须重复发送上次已发送的确认号 ack=u+1。这时服务器进入LAST-ACK
(最后确认)状态。 - (不可以携带数据)客户机收到连接释放报文段后,必须发出确认,之后进入
TIME-WAIT
(时间等待)状态。该报文段的确认位ACK
置 1, 确认号 ack=w+1,序号 seq=u+1 。服务器收到该确认报文段后就进入CLOSED
(连接关闭)状态。客户机进入TIME-WAIT
状态后,还要经过时间等待计时器设定的时间 2MSL (Maximum Segment Lifetime
, 最长报文段寿命)后,才进入CLOSED
状态。若服务器收到连接释放请求后不再发送数据,则从客户机发出FIN
报文段时刻算起,客户机释放连接的最短时间为 1RTT+2MSL, 服务器释放连接的砐短时间为1.5RTT
。
- 参与
- 重传
- 超时:
TCP
维护了RTT
的一个加权平均往返时间RTTS
, 它会随新测量RTT
样本值的变化而变化。显然,超时计时器设置的超时重传时间RetransmissionTime-Out, RTO
应略大于RTTS
, 但也不能大太多,否则当报文段丢失时,TCP
不能很快重传,导致数据传输时延大。 - 冗余
ACK
(冗余确认):TCP
规定每当比期望序号大的失序报文段到达时,就发送一个冗余ACK
,指明下一个期待字节的序号。当发送方收到对同一个报文段的 3 个冗余ACK
时,就可以认为跟在这个被确认报文段之后的报文段已经丢失,这时发送方该报文段执行重传,即快速重传。
- 超时:
- 流量控制:滑动窗口
rwnd
即接收方允许连续接收的能力,单位是字节。发送方总是根据最新收到的rwnd
值来限制自已发送窗口的大小,从而将未确认的数据储控制在rwnd
大小之内,保证发送方不会使接收方的接收缓存溢出。- rwnd=0,即不允许发送方再发送数据。这使得发送方暂停发送的状态将持续到接收方重新发出一个新的窗口值为止。
TCP
为每个连接设有一个持续计时器,只要发送方收到对方的零窗口通知,就启动持续计时器。若计时器超时,就发送一个零窗门探测报文段,而对方就在确认这个探测报文段时给出现在的窗口值。若窗口仍然为零,则发送方收到确认报文段后就重新设置持续计时器。
数据链路层的滑动窗口协议的窗口大小不能动态变化,传输层的窗口大小则可以动态变化。
- 拥塞控制
拥塞控制是让网络能够承受现有的网络负荷,是一个全局性的过程,涉及所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是指点对点的通信量的控制,是个端到端的问题(接收端控制发送端),它所要做的是抑制发送端发送数据的速率,以便使接收端来得及接收。
TCP
还要求发送方维待一个拥塞窗口congestion window, cwnd
,其大小取决于网络的拥塞程度,并且动态地变化。发送方控制拥塞窗口的原则:只要网络未出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去,以提高网络的利用率。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络的分组数,以缓解网络出现的拥塞。-
发送窗口的上限值 = min[rwnd, cwnd]
- 慢开始算法:发送方先令 cwnd=1, 即一个
MSS
。发出若干个报文段后,每收到一个ACK
,cwnd
就 +1,故每经过一个传输轮次(即往返时延RTI
),cwnd
就会加倍, 即cwnd
的值随传输轮次指数增长。为了防止cwnd
增长过大而引起网络拥塞,还需要设置一个慢开始门限ssthresh
(阈值)(通常为 16)。达到阈值后,改用拥塞避免算法。
在慢开始阶段,若 2 \ cwnd \gt ssthresh,则下一个
RTT
后的cwnd
等于ssthresh
,而不等于2cwnd
.- 拥塞避免算法:当 cwnd \ge ssthresh 时,使用拥塞避免算法,每经过一个往返时延
RTT
就将cwnd
+1 。 - 在
TCP
连接建立和网络出现超时时,采用慢开始和拥塞避免算法(ssthresh= cwnd/2, cwnd = 1);当发送方收到 3 个冗余ACK
时,采用快重传和快恢复算法(ssthresh= cwnd/2, cwnd = ssthresh)。
- 特点
考点
-
一台主机中可用的端口数量不超过 65536 ,但能同时存活的
TCP
连接数量远远超过 65536 。以四元组(源IP,源端口,目的IP,目的端口)唯一标识每个
TCP
连接。 -
若不使用
UDP
检验和字段,则填充 0 ;若检验和计算结果恰好为 0 ,则填充全 1 。