5.运输层
5.1 运输层概述
5.1.1进程间基于网络的通信
- 网络层提供主机间的逻辑通信,而对于运输层提供进程间的逻辑通信
- AP1与AP4进程进行通信,AP2与AP3进程进行通,两者通过五层网络层次结构,在运输层时通过不同端口(端口号),进行通信,注意此处的端口不是物理端口号,而是用来去区分进行的标识符,也就是端口号
- 我们可以理解:运输层直接为应用进程间的逻辑通信提供服务
5.1.2 TCP/IP运输层中的两个重要的协议
-
在TCP/IP四层协议中,底层网络接口层未对接入端作规定
-
在网际层中主要使用IP协议来向上层提供不可靠服务来传输数据报
-
在应用层中有些协议是使用可靠传输,有些协议使用不可靠传输服务
-
在运输层中,TCP提供进程间的可靠传输服务,UDP提供不可靠传输服务
TCP(Transmission Control Protocol) | UDP(User Datagram Protocol) |
---|---|
传输控制协议(TCP),向上层提供有连接的、可靠传输服务 | 用户数据报协议(UDP),向上层提供无连接的、不可靠传输服务 |
使用TCP通信需要在通信之前建立TCP连接(逻辑连接),结束通信后必须释放连接 | 使用UDP通信不需要建立连接 |
TCP为了是实现可靠传输,必须实行一些措施:TCP连接管理、确认机制、超时重传、流量控制以及拥塞控制 | UDP实现不可靠传输并不需要这些措施 |
TCP实现机制复杂,首部占用大,占用资源多 | UDP实现简单,首部比较小 |
常见的协议在运输层中使用的协议(TCP/UDP)
5.1.3 运输层端口号、复用和分用的概念
-
端口号:是用于在本地区别不同进程的标记符,我们知道在操作系统中每个进程都自己的PID,但是有于不同操作系统的PID分配规则不同,所以在网络通信中我们使用端口号来进行对进程区分
-
在TCP/IP体系中, 端口号占16比特,范围为0 ~ 65535
- 端口号分为: 服务器端口号 和 客户端端口号
- 服务端端口号又分为熟知端口号 和 登记端口号
- 注意: 端口号具有本地性,不同主机使用相同的端口号不影响网络通信
-
复用: 将上层的数据单元添加首部信息后向下层传输
-
分用(分解): 将下层的数据单元通过端口发送到对应位置
-
在上图中使用了UDP和TCP的复用和分用,复用: UDP将数据报经过运输层添加协议字段值(17),发送到网际层经过IP复用再发送IP数据报,同样的TCP报文段也是如此; TCP分用检测其首部的目的端口号然后发送到是对于端口号的进程处
- OSPF协议不经过应用层的数据封装,直接经网际层封装
5.2 UDP和TCP的对比
5.2.1 无连接的UDP和面向连接的TCP
- UDP是无连接的运输层协议,在传输报文段不需要建立连接可以直接进行数据传输
- TCP是面向连接的运输层协议,在传输报文段之前需要先建立逻辑连接,即进行三次报文握手然后建立TCP连接,在此之后可以进行基于TCP连接的数据传输,在接收数据传输之前需要进行四次报文挥手释放TCP连接
5.2.2 UDP和TCP对单播、多播、广播的支持情况
- UDP:由于识别UDP的标识二元组(目的端口号、目的IP地址),其可以进行单播、多播、广播
- TCP:由于识别TCP的标识四元组(源端口号、目的端口号、源IP地址、目的IP地址),其只可以进单播
5.2.3 UDP和TCP对于应用层报文的处理
- UDP:只是简单的将UDP段加到应用层报文段前面,然后进行向下传输,所以其是面向应用报文的
- TCP:使用TCP协议的运输层,会将应用层传输下来的报文视为一串字节流,然后在运输层中2将其分为大小不一的块,在首部加上TCP段然后传输,所以其是面向字节流的
5.2.4 UDP和TCP对数据传输可靠性的支持情况
- UDP:UDP使用的是不可靠传输,虽然提供差错检测(首部段包括cheeksum,校验和字段),若接收方接收到错误报文,会直接将其丢弃,一般用户对速率要求较高的应用,例如 :P电话、视频流
- TCP:TPC使用的是可靠传输,若传输过程中出现错误,将会利用差错检测检测出错误(CRC,循环冗余校验码),然后再利用可靠数据传输原理来进行实现可靠传输,一般用于对准确性要求高的应用,例如 电子 邮件(STMP)、文件传输(FTP)
5.2.5 UDP首部和TCP首部的对比
- UDP:首部较小,只包括源端口号、目的端口号、长度、校验和,其都为两个字节,即首部为8个字节
- TCP:首部较大,包括源端口号、目的端口号、序号、确认号、数据偏移、(URG、ACK、PSH、SYN、FIN)、窗口、校验和、紧急窗口等,可以看出TCP首部冗余比较多,首部最小20字节,最大80字节
5.2.6 总结
UDP | TCP |
---|---|
无连接,传输数据直接发送报文段 | 面向连接,传输数据前需要三次握手、结束之前需要四次挥手 |
支持单播、多播、广播 | 只支持单播 |
面向应用报文 | 面向字节流 |
提供差错检测,遇到错误报文直接丢弃 | 提供差错检测、可靠传输,对于错误报文直至发送正确报文至接收方 |
包括源端口号、目的端口号、长度、检验和,8字节 | 包括源端口号、目的端口号、序号、确认号等,最少20字节,最多80字节 |
5.3 传输控制协议TCP
5.3.1 TCP报文段的首部格式
1.源端口号和目的端口号
- TCP中源款口号和目的端口号在运输层概述中以及学过
2.序号、确认号、确认标志位ACK
- 在TCP首部中 序号、确认号、ACK与实现可靠传输有关
- 序号: 大小32比特,取值为0 ~ (2^31) - 1,其值的意义是数据载荷中第一个字节的序号,其不断接收数据时,其值会逐渐增大,当超过最大值之后就会回到0
- 确认号:大小为32比特,取值为0 ~ (2^31) - 1,其意义是对方下一个接收的TCP报文中数据载荷的第一个字节的序号,同时也是对之前所有收到数据的确认,当对方收到数据时发送方的确认号将会增大,当超过最大值时就会回到0,可以理解为对反期望下一次接收报文段中数据载荷中第一字节的序号值
- 确认标志位ACK: 只有当ACK为1的时候,确认号才会生效,若建立了TCP连接之后每个数据报的ACK都将是1
例题:
3.数据偏移
- 数据偏移: 4比特,表示的首部的长度,单位为4字节,所以当数据偏移位为:0101时首部长度为5 * 4字节,首部为20字节(最小长度);当数据偏移位为:1111时首部长度为15 * 4字节,首部长度为60字节(最大长度)
- 保留:暂时没有作用
4.窗口
- 窗口:16比特,以字节为单位,表示发送方的接收窗口的大小,代表发送方接收数据的能力
- 在计算机网络中,通常使用接收方的接收数据能力来控制发送方的发送数据速率,这就是拥塞控制
5.校验和
- 16比特,在TCP中校验数据是否正确,不仅经是通过校验位来进行判断,而是在首部之前加上伪首部然后将整报文段来进行差错检测
6.同步标志位SYN
- 同步标志位SYN: 在建立TCP连接时会用到,当发送TCP请求连接报文时SYN=1&&ACK=0,发送TCP响应连接报文时SYN = 1&&ACK = 1,所以在进行三次握手连接过程中,报文段的SYN始终为1
7.终止标志位FIN
- 终止标志位FIN: 当接收方接收当所有数据之后,将会进行四次回收释放连接,FIN = 1,要求进行TCP的释放连接
8.推送标志位PSH
- 在计算机网络中,为了效率TCP发送方可能会延迟报文段的发送,接收方可能会延迟向应用层交付报文段,如果进程在进行实时性较强的通信,可以设置PSH位
- 推送标志位PSH:把PSH推送标志位设置位1,TCP不会延迟报文段的发送,通试接受方也不会延迟向应用层交付报文段
9.紧急标志位URG和紧急指针
- 当应用层有紧急需要发送报文段,可以设置URG紧急标志位和紧急指针
- URG紧急标志位: 该位为1时紧急指针有效;该位为0时紧急指针无效
- 紧急指针:16比特,以字节为单位,当需要发送紧急数据时不需要进行排队直接将紧急数据放到报文段的最首部,紧急指针存储紧急数据的大小,紧急数据之后就是普通数据,注意:使用紧急数据URG紧急标志位必须位1
10.可选选项和填充
- 选项中可以再选择其他功能(可变长度,最长40字节)
- 可选选项:
- 最大报文段长度MSS:指出报文段最大数据载荷长度
- 窗口扩大选项:扩大窗口,提高吞吐率
- 时间戳选型: 用于计算RTT往返时间 用于处理序号超时情况,防止序号绕后PAWS
- 选择确认选项:用来实现选择确认功能
- 填充: 填充0比特,必须将首部段填充至4字节的倍数,因为数据偏移的单位是4比特
5.3.2 TCP运输连接管理
5.3.2.1 TCP三次握手建立连接
- TCP建立运输连接 有三个阶段
- 三次握手建立连接
- 基于已有的TCP可靠传输来进行数据传输
- 数据传输结束之后,通过四次挥手断开连接
- 三次握手的作用:
- TCP双方 能够确认双方发存在
- TCP双方 能够协调一些参数(例如,最大报文段长度、最大窗口长度、时间戳设置)
- TCP双方 能对实体资源进行分配和初始化(例如:缓冲大小、各状态变量、连接表中的项目等)
-
一:一开始TCP双方都是处于关闭状态(CLOSED),首先,服务端创建传输控制块TCB(包括需要记录的重要信息),TCP服务端进入监听状态(LISTEN),TCP服务端是属于被动打开
-
二:然后TCP客户端创建传输控制端TCB,TCP客户端是属于主动打开,发送TCP请求报文段同时进入同步已发送状态(SYN-SENT),TCP请求报文段SYN同步标志位为1,seq序号为客户端随机选择的数字
-
注意:当SYN=1时,数据载荷段不能存储数据且一定会消耗一个序号
-
三:TCP服务端接收到这个报文段之后,发送TCP求请报确认报文段,然后进入同步以接收状态(SYN-RCVD),TCP请求确认报文段SYN=1,ACK=-1,seq序号为y(服务端随机选择),ack(确认号) = x + 1(对之前接收TCP请求报文段作响应)
-
四: TCP客户端节接收到TCP请求确认报文段之后,进入连接已建立状态(ESTABLISHED),然后发送一个普通的确认报文段给服务端,需要注意的是这个报文段可以携带数据载荷,但是对于普通的确认报文段如果不携带数据载荷就不会消耗序号
-
五:当服务端接收到普通确认报文段之后就进入连接已建立状态(ESTABLISHED) ,此时TCP双方就可以进行通信了
例题:
为什么需要三次握手而不是两次握手?
- 为了防止服务端和客户端再关闭连接之后,服务端再次接收到TCP确认请求报文端,此时就会使服务端一直等待客户端的报文段,使资源被白白浪费
- 个人理解:第三次握手其实就是使TCP客户端和TCP服务端同步的作用
5.3.2.2 TCP四次挥手释放连接
- 当TCP客户端发送完了所有数据之后,进程会通知TCP关闭连接,所以是主动关闭,同时发送TCP连接释放报文段,其中FIN=1,ACK=1,然后进入FIN-WAIT-1终止等待1状态
- TCP服务端接收到TCP连接释放报文段之后,进入CLOSE-WAIT关闭等待状态,然后发送普通确认报文段,其中ACK=1,ack=u+1(确认TCP的客户端发送的报文段)
- 此时TCP客户端到TCP服务器进行这个方向的连接就已经关闭,但是客户端还是可以接收服务端发送的报文端,且这个状态可能会持续一段时间
- 若TCP服务端进程也完成任务之后,向客户端发送TCP连接释放报文端,其FIN=1,ACK=1,且seq=u+1,ack=w+1(对客户端发送报文端的确认),并进入LAST-ACK最后确认状态
- 然后客户端发送TCP普通确认报文端之后进入TIME-WAIT时间等待状态,服务端在接收到该确认报文段之后关闭连接,并撤销对应的传输控制块TCB
- 客户端在等2MSL之后关闭连接,并撤销传输控制块TCB
那我们为什么需要一个单独的状态 — 时间等待
- 在实际情况中我们可能出现上述情况,若客户端直接关闭连接且TCP客户端发送的普通确认报文端丢失,服务端会一直进行TCP释放报文端的重发,且客户端不会对该释放报文端理睬,此时服务端就无法进入关闭状态,白白浪费了资源
例题:
- 将三次握手连接 和 四次挥手释放同时考察
- 注意:只需要直到SYN=1 或者 FIN=1的报文端一定会消耗序号,普通确认报文端如果没有携带数据载荷就不会消耗报文段
TCP保活计时器
- TCP保活计时器:当TCP客户端出现故障无法进行传输时,使服务端可以检测到故障的方法
- 通常保活计时器的计数时长为2hour,当该时长内没有接收客户端发送的数据时,服务端会发送TCP探测报文端,如果没有接收客户端的回应,之后还会每隔75second再次发送一遍,若发送10次之后还没有收到客户端的响应则关闭这个连接
5.3.3 TCP的流量控制
- 对于TCP的流量控制,是由于接受方的接收能力不足以接收发送发送的数据而产生的接受区溢出问题
- 发送方会根据接收方发送的非零窗口通知来改变发送窗口的大小
- 那么如果非零窗口通知丢失该怎么办呢?
例题:
5.3.4 TCP的拥塞控制
5.3.4.1 拥塞控制的基本概念
- 对于拥塞控制就是为了经量减少因为拥塞问题而导致整个网络中出现的吞吐量减少
5.3.4.2 拥塞控制的基本方法
- 很多地方会把流量控制和拥塞控制混淆,其实两者是完全不同的问题,流量控制解决是因为接收方能力不足接收发送方的数据而产生的接收区溢出问题, 而拥塞控制解决链路中数据超过网络承受能力的问题
- 我们在这里使用闭环控制中的隐式反馈算法
5.3.4.3 拥塞控制的四种方法
- TCP的拥塞控制方式有四种:慢开始、拥塞避免、快重传、快恢复四种
- 注意:TCP使用的累计确认
例题:
- 注意:发送方的发送窗口大小 = min(拥塞窗口,接收方窗口)
5.3.5 TCP拥塞控制与网际层拥塞控制的关系
5.3.6 TCP可靠传输的实现
- 在TCP可靠传输的实现中,使用字节流为单位来进行传输
- 在TCP中可靠传输中,ack_n选择重传协议的表示与TCP协议的表示不完全行同, 但是其意思是一致的,在选择重传协议中表示已经接收到n序号的数据,而期望接收当n + 1序号的数据;而在TCP协议中表示已经接收到n - 1序号的数据,而期望接收当n序号的数据
- TCP可靠传输中,把发送窗口分为三部分即 已发送且确认可以删除的部分(后沿之后)、 发送窗口、不允许发送(前沿之前)
- 对于后沿部分移动情况: 不动、 前移
- 对于前沿部分移动情况:前移、不动(没有收到报文端、收到报文端但是刚好窗口缩小)、 向后收缩(接收方窗口缩小)
- 通过将发送窗口分为三部分,由P1、P2、P3三个指针来描述发送窗口
- P1之前是已经发送且确认部分、P1到P2是已经发送但是还未收到确认部分,P2到P3是发送窗口内但是还未发送的部分、P3之前是不允许发送部分
- P3 - P1 = 发送窗口大小, P2 - P1 = 已发送但是还未收到确认的字节数, P3 - P2 = 允许发送但是还未发送部分
5.3.7 TCP超时重传时间的选择
- 对于计算往返时间,因为两次网络往返时间可能由于网络问题导致往返时间差别较大,所以使用 RTT_s = (1 - α) 旧的RTT_s + α * 新的RTT样本*
- 在TCP超时重传时间的计算如上
- 对于报文丢失时,我们计算RTT 和 RTO时会误差比较大,此时测量误差比较大
- 注意:当产生报文丢失时,我们直接将RTO 设置为 RTO = 2 * 旧的RTO
例题:
5.3.8 TCP的选择确认SACK
- 在之前的的TCP超时重传时,我们使用的累计确认,当然TCP中也提供了选择重传(选择确认SACK)
- 如图中,有两部分缺失字节流,我们要求只重传缺失的字节流而不是重传最小确认序列的报文端,此时我们可以使用选择确认SACK
- 为了使用确认SACK,我们要在选项中 设置一个允许SACK选项(1B)、 SACK选择长度(1B)、而描述每个边界需要4B,一个字节块需要两个边界(8B),由于选项长度最长40B,所以最长只能由4个字节块,即32B