运输层知识梳理
目录
运输层概述
定义
运输层,也叫传输层,实现端对端的传输,应用层进程得到消息后交给传输层变成数据段,然后交予网络层。
它位于网络层之上,应用层之下,为运行在不同主机上的应用进程之间提供了逻辑通信功能。
与网络层的对比
服务层 | 定义 | 数据传输 | 协议 |
---|---|---|---|
运输层 | 不同主机上的进程之间的逻辑通信 | 报文段,segment | TCP、UDP |
网络层 | 不同主机之间的逻辑通信 | 数据报,datagram | IP协议 |
数据加封与解封的过程
运输层的多路复用与多路分解
- 由网络层提供的主机到主机交付服务延伸到为运行在主机上的应用程序提供进程到进程的交付服务。
- 将运输层报文段中的数据交付到正确的套接字的工作叫做多路分解。
- 在源主机从不同套接字中收集数据块并传递到网络层的工作叫做多路复用。
- 多路分解
- 接收主机将一个到达的运输层报文段定向到适当的套接字,在接收端,运输层检查报文段的一些字段,标识出接收套接字,进而将报文段定向到该套接字。
具体描述: 在主机上的每个套接字能够分配一个端口号,当报文段到达主机的时候,运输层检查报文段的目的端口号,并将其定向到相应的套接字,然后报文段中的数据通过套接字进入其所连接的进程。 - 多路复用
- 在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息从而生成报文段,然后将报文段传递到网络层
运输层协议概述
基本责任
- 将两个端系统间IP的交付服务拓展为运行在端系统上的两个进程之间的交付服务。(数据交付)
- 通过在其报文段首部中包括的差错检查字段来提供完整性检查。(查错检查)
UDP协议
优点:
1. 适用于实时应用,通常要求最小的发送速率,不希望过分地延迟报文段的传送,且能容忍一些数据丢失
2. 无需连接建立(不会有建立连接的时延)
3. 无连接状态(不需要跟踪一些参数,比如接收和发送的缓存、拥塞控制的参数以及序号与确认号的参数)
4. 分组首部开销小(TCP20个字节、UDP8个字节)
问题:缺乏拥塞控制能够导致UDP发送方和接收方之间的高丢包率。
举例: RIP路由选择表的更新、SNMP承载网络管理数据、NFS远程文件服务器、DNS
UDP报文段
源端口号以及目的端口号
用于唯一标识套接字,指示该报文段所要交付的套接字。端口号一般是16个bit,范围[0,65535]。其中0-1023是周知端口号,比如HTTP是80端口,FTP是21端口
长度
UDP用户数据报的长度(首部字段和数据字段),其最小值是8,也即是只有首部。
校验和
检测UDP用户数据报在传输的过程中是不是有错,有错就丢弃。
TCP协议
可靠数据传输(流量控制、序号、确认和定时器);拥塞控制
TCP套接字是一个四元组(源端口号,源主机IP地址,目的端口号,目的IP地址)来标识。
特点
1. 因特网运输层的面向连接的可靠的运输协议(确认、定时器、重传以及序号机制)
2. 面向连接
3. 全双工服务
TCP报文段
TCP报文段首部的前20个byte是固定的,后面4N字节是根据需要而增加的选项,因此首部的最小长度为20个字节。
首部固定部分的字段意义:
1. 源端口和目的端口字段
各占16bit(2个字节)。端口是运输层与应用层的服务接口。
运输层的复用和分解要通过端口号来与对应的套接字关联。
2. 序号
32bit(4个字节)。TCP是面向字节流的,每个字节都按顺序编号,起始序号要在建立连接时设置。它的值等于所发送数据的第一个字节。
3. 确认号
32bit(4个字节)。期待收到对方的下一个报文段等的第一个字节的序号。比如主机A已经收到了0-535的所有字节,那么它等待主机B 的数据流中字节536以及之后的所有字节。因此确认号为536
4. 数据偏移
4bit。表明该TCP报文段的数据起始处离TCP报文段的起始处有多远。也就是表明TCP首部的长度,最大可以表示60(4*15)字节。也就是说TCP报文首部不能超过60byte。
5. 保留字段
6bit。保留为今后使用,但目前应置为零。
6. 紧急URG
1bit。当 URG ==1 时,表明紧急指针字段有效。告诉系统该报文有紧急数据,应尽快传送。
7. 确认ACK
1bit。当ACK=1,确认号字段才有效,当ACK=0,确认号字段无效。
TCP规定,在连接建立后所有传送的报文段都必须把ACK置1.
8. 推送PSH
1bit。当两个进程通信时,有时一端的进程希望键入一个命令后,能立即收到对方的响应,这时TCP就可以将PSH=1,并立即创建一个报文段发送出去,接收方TCP收到PSH=1,就会尽快交付给接收端进程,而不会再等整个缓存填满后再交付。
9. 复位RST(ReSeT)
1bit。当 RST=1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接
RST置1可以用来拒绝一个非法的报文段或者拒绝打开一个连接。
10. 同步SYN
1bit。在建立连接时用来同步序号,当SYN=1&&ACK=0,表示这是一个请求连接的报文段,(三次握手的第一步)。若对方同意建立连接,则在响应报文段中使得SYN=1&&ACK=1。(三次握手的第二步)。故SYN=1:表示这是一个连接请求和连接接收报文。、
11. 终止FIN
1bit。用来释放一个连接,当FIN=1,表示此报文段发送方的数据发送完毕,并要求释放连接。
12. 窗口
16bit(2个字节)。接收方告知发送方现在允许对方发送的数据量。
13. 检验和
16bit(2个字节),检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部。
14. 紧急指针
16bit(2个字节),当URG=1,紧急指针才有意义,指出本报文段中的紧急数据的字节数。
15. 选项
最长为40字节
TCP连接建立与关闭
TCP建立连接
就是我们常说的通过三次握手建立TCP连接。
第一步:客户端的TCP想服务器端的TCP发送一个特殊的TCP报文段,称为SYN报文段(syn设置为1),不包含应用层数据,随机选择一个初始序号client_isn。该报文段会被封装到一个IP数据报中,并发送给服务器。
第二步:服务器收到ip数据报后,提取出TCP SYN报文段,为该TCP分配TCP缓存和变量,并向该客户TCP发送允许连接的报文段。这个报文段也不包含应用层数据。首部包含三个重要信息:SYN比特设置为1,确认号设置为client_isn+1;服务器选择自己的随机序号server_isn。该报文也被称为SYNACK segment
第三步:客户机收到SYNACK报文段后,给该连接分配缓存和变量。客户机向服务器发送另外一个报文段,对服务器的允许连接的报文段进行确认(确认字段设置为server_isn+1)。因为连接已经建立了,因此SYN比特设置为0。这一阶段可以在报文段负载中携带客户到服务器的数据。
SYN洪泛攻击
前提——如果某用户不发送ACK来完成三次握手的第三步,最终服务器将终止半开连接并回收资源
攻击——攻击者发送大量的TCP SYN报文段,而不完成第三次我收的步骤,服务器不断为这些半开连接分配资源,但从未使用,导致服务器的连接资源被消耗殆尽
解决——SYN cookie,服务器不为半开连接分配资源,生成初始TCP***,成为cookie买服务器不记忆该cookie或者对应于SYN的其他状态信息。通过cookie来验证客户是否合法
TCP关闭连接
过程描述
1. 客户TCP向服务器进程发送一个特殊的TCP报文段,FIN比特设置为1
2. 服务器接收到该报文之后,向发送方一个确认报文段
3. 然后服务器发送自己的终止报文段,FIN设置为1
4. 客户机对这个服务器的终止报文进行确认。此时,两台主机用于该连接的所有资源都被释放了。
TCP可靠数据传输问题
UDP传输数据不可靠,具体表现:
- 发送方不知道UDP数据段传达到接收方了没有,无反馈信息
- 发送方有多少就发多少,不会理会接收方实际可接收的数据大小
因此可靠性传输需要考虑两个方面:
1. 接收到消息后的反馈机制
2. 接收方对于数据的承载能力
反馈机制
链路层也使用了可靠数据的传输,通过停等协议、滑动窗口协议等,但由于网络层的IP协议是不可靠的,即使在链路层上不会发生丢失和错序,但是在路由器(网络层)上可能发生丢包。
TCP传输使用选择性重传(selective repeat)的传输方式。不选用停等协议是因为传输层中端到端的延迟很大。选择性重传用到了***和确认号
确认号+序号
- 客户端发送第一个报文段,序号为x;第一个确认号字段为y-1。
- 然后服务端成功接收报文段后,提供一个确认,确认号为x+1,表示已经收到x以及之前的数据,期待接收x+1以及之后的数据。这里的报文段序号设置为y.
-
接着第三个报文段由客户发往服务器。确认已经收到服务器发来的数据。确认号为y+1,并且序号为x+1.
TCP发送窗口与接收窗口
附加问题及解决方案-
死锁问题
当接收缓存清空后,需要发送一个win=1000的ACK,当它丢失时,会出现死锁。
解决方案
persist timer, 发送端接收到一个win=0的ACK后,每隔一段时间向接收端发送给一个长为1byte的信号,直到收到win!=0的ACK Silly Window Syndrome(sender)
发送方每次只生成少量数据
解决方案
delay ACK,等待接收端有没有向发送端传输的数据,等到有反向传输的数据的时候进行捎带(piggyback)的确认Silly Window Syndrome(receiver)
接收方每次只需走少量数据
解决方案
Nagle算法,第一个TCP段无论多小立即发送,下一个TCP段达到MSS或者收到上一段TCP段的确认包,才可发送
如果接收窗口接近全满,上层每次只取走少量数据,可用Clark算法,剩余接收窗口恢复到接收窗口的一半或者剩余窗口恢复到MSS,才发送ACK-
TCP超时时间
与链路层不同,传输层的超时时间随网络实际环境时常发生改变,而且变化比较剧烈。因此不能强制定一个值,而要动态调整。
超时时间太长,丢包代价太大
超时时间太短,超时重传严重
原始计算方法
TCP超时时间为2xEstimatedRTT。
Jacobson’s Algorithm
TCP超时时间为EstimatedRTT + 4*DevRTT。
还有Karn算法,长肥管道Long Fat Pipe等,这里就不赘述啦。
-
死锁问题
TCP拥塞控制问题
由于发送方到接收方之间的信道是公用的,因此如果发送方不考虑中间信道的容量随意发送就可能出现拥塞。拥塞会导致延迟严重,甚至大量丢包
- TCP必须使用端到端拥塞控制。(区别于网络辅助手段)
- 方法:让每一个发送方根据所感知到的网络拥塞程度来限制其能向链接发送流量的速率。
- 不拥塞——加快发送流量的速率
- 拥塞——减慢发送流量的速率
发送端由一个接收缓存、一个发送缓存和几个变量组成。
拥塞控制机制需要跟踪一个额外的变量,拥塞窗口,cwnd。它对于一个TCP发送方能向网络中发送流量的速率进行了限制。
这里我们假设接收窗口无限大,发送方未被确认的数据量仅受限于cwnd
可以通过调节cwnd来调整发送方向连接发送数据的速率
① 限制发送流量
运行在发送方的TCP拥塞控制机制跟踪一个额外的变量,即拥塞窗口(congestion window。cwnd)
调节cwnd值以控制发送速率
② 感知出现拥塞
过度拥塞的时候,路由器的缓存会溢出,引起一个数据报被丢弃,引起发送方的丢包事件
丢包事件:出现超时或者收到来自接收方的三个冗余ACK
③ 确定应当发送的速率
这里需要用到TCP拥塞控制算法:慢启动;拥塞避免;快速恢复
慢启动算法
阶段 | 阶段行为 | 结束的方式 |
---|---|---|
慢启动 | cwnd的值以一个MSS开始并且每当传输的报文段首次被确认,就指数增加MSS,1,2,4…每经过一个RTT,发送的速率翻番。 | 第一次结束:(出现由超时指示的丢包时间)将cwnd设置为1,然后重新开始慢启动过程,并且设置ssthresh(慢启动阈值)设置为cwnd的一半。第二次结束:(当cwnd达到或者超过ssthresh),TCP转移到拥塞避免阶段。第三次结束(检测到3个冗余ACK):执行快速重传并进入快速恢复状态 |
拥塞避免 | 此时cwnd的值大约是上次拥塞的值的一半,每次收到确认,将cwnd增加一个MSS | 出现超时时,cwnd的值被设置为1个MSS,当丢包发生时,ssthresh更新为cwnd值的一半;当收到3个冗余的ACK时,将ssthresh的值记录为cwnd的值的一半,然后进入快速恢复状态 |
快速恢复 | 每收到一个冗余的ACK,cwnd将增加一个MSS | 当对丢失报文段的一个ACK到达时,TCP在降低cwnd后进入拥塞避免状态。如果出现超时事件,cwnd设置为1个MSS,并且ssthresh的值设置为cwnd值的一半,然后迁移到慢启动状态 |
TCP Tahoe机制
- 把上一次发生超时或重复ACK时对应的拥塞窗口大小的一半设为阈值
- 每成功传输一个TCP数据段,小于阈值时指数增加(较上次加倍),大于阈值后加性增加(较上次加1MSS)
- 每出现三个对同一TCP数据段的ACK或者是每发生一次超时后更新阈值,同时拥塞窗口大小重新回到1MSS
TCP Reno机制
- 每出现三个对同一TCP数据段的ACK或者是每发生一次超时后更新阈值,同时拥塞窗口大小回到阈值大小(快速恢复机制)
AIMD[Additive-Increase, Multiplicative Decrease]算法
假定丢包都是由三个冗余的ACK而不是超时来指示,忽略慢启动的阶段。
每个RTT内cwnd线性增加一个MSS(加性增),出现冗余ACK事件后,cwnd减半 (乘性减)