根据计算机网络微课堂课程,同时参考了掘金-BloothOfYouth,总结笔记 !
第五章 运输层
5.1 运输层概述
运输层为 不同主机上的应用进程 提供直接的通信服务,
其协议又称为端到端协议。
进程Ap1与Ap4之间进行基于网络的通信,进程Ap2与Ap3之间进行基于网络的通信
在运输层使用不同的端口,来对应不同的应用进程
然后通过网络层及其下层来传输应用层报文
接收方的运输层通过不同的端口,将收到的应用层报文,交付给应用层中相应的应用进程
这里端口并不是指看得见、摸得着的物理端口,而是指用来区分不同应用进程的标识符
总结
5.2 运输层端口号、分用与复用的概念
端口号16bit,范围为 0 ~ 65535
0 ~ 1023:熟知端口号
1024 ~ 49151:登记端口号
49152 ~ 65535:短暂端口号
发送方的复用和接收方的分用
计算机的某些进程发送的不同应用报文,在运输层使用UDP进行封装,称之为“UDP复用”
计算机的某些进程发送的不同应用报文,在运输层使用TCP进行封装,称之为“TCP复用”
运输层用不同端口号来区分不同进程,在网络层都需要用IP协议封装成IP数据报,“IP复用”
IP数据报首部中协议字段的值,用来表明IP数据报的数据载荷是何种协议数据单元
6-》TCP,17-》UDP
根据协议字段,上交到运输层的相应协议,
运输层根据UDP和TCP应用报文进行分用,也就是根据不同端口号交给相应的应用进程
无论在运输层使用何种协议,在网络层都需要用IP协议进行封装
举例:运输层端口号
在浏览器输入域名,回车浏览
然后用户PC中的DNS客户端进程会发送一个DNS查询请求报文
DNS查询请求报文需要使用运输层的UDP协议
首部中的源端口字段的值,在短暂端口号49151~65535中挑选一个未被占用的,
用来表示DNS客户端进程
首部中的目的端口字段的值:53,是DNS服务器端进程所使用的熟知端口号
之后将UDP用户数据报封装在IP数据报中,通过以太网发送给DNS服务器
DNS服务器收到该IP数据报后,从中解封出UDP用户数据报
UDP首部中的目的端口号为53,这表明应将该UDP用户数据报的数据载荷部分,
也就是DNS查询请求报文,交付给本服务器中的DNS服务器端进程
DNS服务器端进程解析DNS查询请求报文的内容,然后按其要求查找对应的IP地址
之后,会给用户PC发送DNS响应报文,DNS响应报文需要使用运输层的UDP协议封装成UDP用户数据报
其首部中的源端口字段的值设置为熟知端口号53,表明这是DNS服务器端进程所发送的UDP用户数据报,
目的端口的值设置为49152,这是之前用户PC中发送DNS查询请求报文的DNS客户端进程所使用的短暂端口号
将UDP用户数据报封装在IP数据报中,通过以太网发送给用户PC
用户PC收到该数据报后,从中解封出UDP用户数据报
UDP首部中的目的端口号为49152,这表明应将该UDP用户数据报的数据载荷部分,
也就是DNS响应报文,交付给用户PC中的DNS客户端进程
DNS客户端进程解析DNS响应报文的内容,
就可知道自己之前所请求的Web服务器的域名对应的IP地址
总结
5.3 UDP和TCP的对比
UDP无连接,任何时候都可以传输
TCP面向连接,需要经过三次握手建立连接,传输数据,四次挥手释放连接
UDP支持广播、多播、单播
TCP基于可靠信道,只支持单播
UDP面向应用报文,对于应用层交付的数据不合并也不拆分,直接封装传输
TCP面向字节流,将数据块看出一连串的字节流,编号并存储在发送缓存中,
根据发送策略构建TCP报文段发送,接收方接收到接收缓存中。
并不能保证接收方进程收到的数据块和发送方发送的数据块有对应大小的关系。
UDP向上提供无连接不可靠的传输服务,
“检验和”检验数据正确性,误码时丢弃报文,丢失报文时不做处理
TCP向上提供面向连接可靠的数据传输服务,将其想象成基于TCP的可靠信道进行传输
不会出现传输差错(误码、丢失、乱序、重复)
UDP数据报格式
首部 + 数据部分
首部:源端口2 + 目的端口2 + 长度2 + 检验和2(8字节)
TCP数据报格式
首部 + 数据部分
首部: 源端口16bit + 目的端口16bit
序列号32bit
确认号32bit
数据偏移4bit + 保留6bit + 6个标志位 + 窗口16bit
检验和16bit + 紧急指针16bit (以上共20字节,固定部分)
选项(长度可变) + 填充 (可选40字节,可选部分)
总结
5.4 TCP流量控制
流量控制:滑动窗口机制
举例
假设TCP发送的每个报文段可携带100字节数据,
在TCP建立连接时,接收方告诉发送方自己的rwnd为400,
发送方设置自己的发送窗口swnd为400
发送方发送三次报文,第三次丢失
(ACK标志位=1,说明是确认报文段)
(ack=201,说明序号201之前的数据段已被正确接收,现在希望收到201以及之后的数据)
(rwnd是窗口字段)
接收方累计确认,确认号为201,并重新说明接收窗口长度为300
发送方收到累计确认,向前移动流量窗口,并将流量窗口设置为300
因为201之前的数据被累计确认了,从而可以将其从缓存中删除
继续发送301~400、401~500的两个报文段
201~300的报文段未被确认,等待计时器超时重发
收到确认报文段
发送方将窗口往前滑动,设置为100,将确认报文从缓存中删除
发送501~600报文段
后收到确认报文段,rwnd=0
窗口往前滑动,并设置为0,不能发送数据
接收方重新发送报文,告知rwnd
若出现该报文丢失?
发送方一直等待非零窗口通知,接收方一直等待数据报文,造成死锁...
如何解决?
采用 持续计时器 + 零窗口探测报文 进行解决
TCP在一方接收到零窗口通知时,会启用持续计时器
若在计时器之内收到非零窗口通知,不会造成死锁
若计时器超时,则发送一个零窗口探测报文(仅1字节):
若有非零窗口通知,则可以继续发送数据;
若继续为零窗口通知,则重启持续计时器
ps:TCP规定,即使接收窗口为0,也必须接受零窗口探测报文段、确认报文段、以及紧急数据报文段
疑问:若零窗口探测报文段丢失了怎么办?
在零窗口报文段发送时,会启动该重传计时器
TCP发送方窗口 = min(拥塞窗口,流量控制窗口)
总结
5.5 TCP的拥塞控制
拥塞控制算法
发送方维护 拥塞窗口cwnd ,
维护原则:若网络没有拥塞,则cwnd增大一些,若拥塞,则减少
判断依据:是否出现超时重传
图例:
传输轮次:
发送方给接收方发送数据报文段后,接收方给发送方发发回相应的确认报文段
一个传输轮次所经历的时间其实就是往返时间,往返时间并非是恒定的数值
使用传输轮次是为了强调把拥塞窗口所允许发送的报文段都连续发送出去,并受到了对已发送的最后一个报文段的确认
拥塞窗口:
它会随网络拥塞程度,以及所使用的拥塞控制算法动态变化
慢开始和拥塞避免
慢开始算法(slow start):
思路:从小到大增加拥塞窗口数值
变量一:cwnd初值设为1
变量二:ssthresh,慢开始门限,设置为16
每经过一个传输轮次,cwnd加倍。
1 2 4 8 16
窗口大小按指数增加,并不慢!
拥塞避免(congestion avoidance)
思路:让拥塞窗口 cwnd 缓慢地增大,避免出现拥塞。
每经过一个传输轮次,拥塞窗口 cwnd = cwnd + 1。
使拥塞窗口 cwnd 按线性规律缓慢增长。
在拥塞避免阶段,具有 “加法增大” (Additive Increase) 的特点
如果在发送过程中出现部分报文段丢失,这必然会造成发送方对这些丢失报文段的超时重传
出现超时重传,因此判断为网络出现拥塞:(拥塞出现时的窗口值记为c1)
将ssthresh设置为 c1 / 2;
将cwnd设置为初值1,重新开始慢开始算法
快重传和快恢复
快重传
快恢复
快重传(fast retransmit)
快恢复(fast recovery)
判断依据:收到3个重复确认(拥塞出现时的窗口值记为c1)
将cwnd 和 ssthresh 设置为 c1,重新开始拥塞避免算法
5.6 TCP超时重传时间的选择
RTT(Round Trip Time):一个连接的往返时间,即数据发送时刻到接收到确认的时刻的差值;(在图中可看为RTTO)
RTO(Retransmission Time Out):重传超时时间,即从数据发送时刻算起,超过这个时间便执行重传。
RTT和RTO 的关系是:由于网络波动的不确定性,每个RTT都是动态变化的,所以RTO也应随着RTT动态变化。
如果超时重传时间RTO的值设置得比RTT0的值小很多,
这会引起报文段不必要的重传,使网络负荷增大
如果超时重传时间RTO的值设置得远大于RTT0的值,
这会使重传时间推迟的太长,使网络的空闲时间增大,降低传输效率
超时重传造成RTT计算比较困难
5.7 TCP可靠传输的实现
5.8.1 TCP的运输连接管理 - TCP的连接建立
TCP连接建立要解决的三个问题
最初,客户端和服务端TCP进程都处于关闭状态(CLOSED)
一开始,TCP服务器进程首先创建传输控制块,
用来存储TCP连接中的一些重要信息。
例如TCP连接表、指向发送和接收缓存的指针、指向重传队列的指针,当前的发送和接收序号等
之后,就准备接受TCP客户端进程的连接请求
此时,TCP服务器进程就进入监听状态,等待TCP客户端进程的连接请求(LISTEN)
TCP服务器进程是被动等待来自TCP客户端进程的连接请求,因此称为被动打开连接
TCP客户进程也是首先创建传输控制块
在打算建立TCP连接时,向TCP服务器进程发送TCP连接请求报文段,并进入同步已发送状态(SYN_SENT)
TCP连接请求报文段首部:
同步位SYN被设置为1,表明这是一个TCP连接请求报文段
序号字段seq被设置了一个初始值x,作为TCP客户端进程所选择的初始序号
请注意:TCP规定SYN被设置为1的报文段不能携带数据,但要消耗掉一个序号
由于TCP连接建立是由TCP客户端主动发起的,因此称为主动打开连接
TCP服务器进程收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接收状态(SYN_RCVD)
TCP连接请求确认报文段首部:
同步位SYN和确认为ACK都设置为1,表明这是一个TCP连接请求确认报文段
序号字段seq被设置了一个初始值y,作为TCP服务器进程所选择的初始序号,
确认号字段ack的值被设置成了x+1,这是对TCP客户进程所选择的初始序号(seq)的确认
请注意:这个报文段也不能携带数据,因为它是SYN被设置为1的报文段,但同样要消耗掉一个序号
TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并进入连接已连接状态(ESTABLISHED)
普通的TCP确认报文段首部:
确认位ACK被设置为1,表明这是一个普通的TCP确认报文段
序号字段seq被设置为x+1,这是因为TCP客户进程发送的第一个TCP报文段的序号为x,所以TCP客户进程发送的第二个报文段的序号为x+1
确认号字段ack被设置为y+1,这是对TCP服务器进程所选择的初始序号的确认
请注意:TCP规定普通的TCP确认报文段可以携带数据,但如果不携带数据,则不消耗序号
TCP服务器进程收到该确认报文段后也进入连接已建立状态(ESTABLISHED)
现在,TCP双方都进入了连接已建立状态,它们可以基于已建立好的TCP连接,进行可靠的数据传输
为什么TCP客户进程最后还要发送一个普通的TCP确认报文段?
能否使用“两报文握手”建立连接?
这是为了防止已失效的连接请求报文段突然又传送到了TCP服务器,因而导致错误(服务器已建立连接,而客户端却处于关闭状态,浪费资源)
5.8.2 TCP的连接释放
现在TCP客户进程和TCP服务器进程都处于连接已建立状态(ESTABLISHED)
TCP客户进程的应用进程通知其主动关闭TCP连接
TCP客户进程会发送TCP连接释放报文段,并进入终止等待1状态(FIN_WAIT1)
TCP连接释放报文段首部:
终止位FIN和确认为ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认
序号seq字段的值设置为u,它等于TCP客户进程之前已传送过的数据的最后一个字节的序号加1
确认号ack字段的值设置为v,它等于TCP客户进程之前已收到的、数据的最后一个字节的序号加1
请注意:TCP规定终止位FIN等于1的报文段即使不携带数据,也要消耗掉一个序号
TCP服务器进程收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并进入关闭等待状态(CLOSE_WAIT)
TCP客户端进程收到确认报文段后,进入终止状态2(FIN_WAIT2)
普通的TCP确认报文段首部:
确认位ACK的值被设置为1,表明这是一个普通的TCP确认报文段
序号seq字段的值设置为v,它等于TCP服务器进程之前已传送过的数据的最后一个字节的序号加1,这也与之前收到的TCP连接释放报文段中的确认号匹配
确认号ack字段的值设置为u+1,这是对TCP连接释放报文段的确认
TCP服务器进程应该通知高层应用进程,TCP客户进程要断开与自己的TCP连接
此时,从TCP客户进程到TCP服务器进程这个方向的连接就释放了
这时的TCP连接属于半关闭状态,也就是TCP客户进程已经没有数据要发送了
但如果TCP服务器进程还有数据要发送,TCP客户进程仍要接收,也就是说从TCP服务器进程到TCP客户进程这个方向的连接并未关闭
由于TCP连接释放是由TCP客户进程主动发起的,因此TCP服务器进程对TCP连接的释放称为被动关闭连接
TCP服务器进程发送TCP连接释放报文段并进入最后确认状态(LAST_ACK)
该报文段首部:
终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认
序号seq字段的值为w,这是因为在半关闭状态下,TCP服务器进程可能又发送数据
确认号ack字段的值为u+1,这是对之前收到的TCP连接释放报文段的重复确认
TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段,之后进入时间等待状态(TIME_WAIT)
该报文段首部:
确认为ACK的值被设置为1,表明这是一个普通的TCP确认报文段
序号seq字段的值设置为u+1,这是因为TCP客户进程之前发送的TCP连接释放报文段虽然不携带数据,但要消耗掉一个序号
确认号ack字段的值设置为w+1,这是对所收到的TCP连接释放报文段的确认
TCP服务器进程收到该报文段后就进入关闭状态,而TCP客户进程还要经过2MSL后才能进入关闭状态
TCP客户进程在发送完最后一个确认报文后,
为什么不直接进入关闭状态?而是要进入时间等待状态?
因为时间等待状态以及处于该状态2MSL时长,
可以确保TCP服务器进程可以收到最后一个TCP确认报文段而进入关闭状态
另外,TCP客户进程在发送完最后一个TCP确认报文段后,
在经过2MSL时长,就可以使本次连接持续时间内所产生的所有报文段都从网络中消失,
这样就可以使下一个新的TCP连接中,不会出现旧连接中的报文段
TCP保活计时器
TCP保活计时器的作用
TCP双方已经建立了连接,后来,TCP客户进程所在的主机突然出现了故障
TCP服务器进程以后就不能再收到TCP客户进程发来的数据
因此,应当有措施使TCP服务器进程不要再白白等待下去
5.9 TCP报文首部格式
源端口、目的端口
序号、确认号
数据偏移、保留
窗口
校验和
标志位
SYN标志位
FIN标志位
RST复位标志位
PSH推送标志位
URG紧急标志位
选项、填充