传输层协议TCP
传输层协议TCP
1.初步认识
TCP协议和UDP协议一样,都是位于传输层的协议,相较于UDP,TCP被广泛应用于那些不能容忍数据丢失或出错的场景
以下是TCP协议三大特征点:
特性 | 核心描述 | 核心机制 |
---|---|---|
1. 面向连接 | 数据传输前必须建立逻辑连接,传输结束后断开连接。确保通信双方准备好再进行传输,为可靠传输奠定基础。 | 三次握手 (建立连接) 四次挥手 (断开连接) |
2. 可靠传输 | 确保数据无差错、不丢失、不重复且按序地从一端送达另一端。是TCP协议最根本的价值。 | 确认与重传 (ACK) 超时重传 数据包排序 |
3. 流量与拥塞控制 | 流量控制:防止发送方发送数据过快,导致接收方的缓冲区溢出。 拥塞控制:防止发送方发送数据过快,导致网络发生拥堵。 | 滑动窗口 (流量控制) 慢启动、拥塞避免等算法 (拥塞控制) |
主要应用在以下场景:
•网页浏览 (HTTP/HTTPS)
•电子邮件 (SMTP)
•文件传输 (FTP)
•远程登录 (SSH)
2.TCP协议的格式
源端口&目标端口(16位):标识发送和接受应用程序的端口号,用于多路复用和解复用
**序列号(32位):本段文段所发送数据的第一个字节的编号,**用于数据排序和可靠性
**补充:**TCP协议将数据视作为一个连续的字节流,每一个字节都按顺序分配了唯一的序列号
后面的每一个字节的序列号为这个序列号+1
**确认号(32位):期望收到对方下一个报文段的第一个数据字节的序列号,**表示此序号之前所以数据已经正确接受,用于确认机制。
数据偏移(4位):记录TCP头部的长度,因为可选字段长度可变,最小是5(即20字节)
**[**首部长度的单位是4字节,范围是0101到1111(即20字节到60字节 ]
**控制标志(6位):**用于控制连接状态:
- URG:紧急指针有效
- ACK:确认号有效(建立连接后通常总为1)
- PSH:接收方应尽快将数据交付应用层
- RST:重置连接(通常表示异常中断)
- SYN:同步序列号,用于建立连接
- FIN:发送端数据发送完毕,用于断开连接
窗口(16位):接收方告诉发送方自己还能接受多少数据,实现流量控制的核心机制
**校验和(16位):**用于检验TCP头部和数据在传输中是否出错
**紧急指针(16位):**当URG标志为1时才有效,指示紧急数据在报文段中的位置
[紧急数据是在报文的有效载荷的特定偏移处,其最大的作用就是希望对方优先处理,但在现代网络中URG和紧急数据(一个字节)在现代网络通信中的主要作用已经基本失效,其他的小作用也都已经边缘化了 ]
**可选字段(可变):**用于支持一些高级功能,如最大报文段长度(MSS)、窗口缩放因子等
2.1 序列号和确认号
确认序号就是对应序列号+1,含义是我已经成功且按序地接收到了直到序列号N-1为止的所有数据,请从序列N开始的字节,也就是从确认序号开始发送字节
比如你发送了数据的序号是0~100,那么确认序号就是101.
确认序号的存在十分重要它直接关乎到了传输中的两大特点:
高效:这里的高效体现在捎带确认,把数据发送和确认接收,合并到一个报文里完成,从而避免多次发送报文
**可靠:**有了确认序号就可以避免对方发过来的数据的序号与之前的序号重合从而发生数据混乱
3.TCP建立连接的过程
TCP建立连接的过程可以概括为**“三次握手”和“四次挥手”**,而这两个操作都依赖着控制标志位
假设现在有两个主机A和B,以下是二者建立连接的过程:
三次握手
**第一次握手:**SYN=1 A向B发送连接请求。SEQ = x
(A的初始序列号)
**第二次握手:**SYN=1,ACK=1 B同意建立连接。ACK = x + 1
(确认A的序列号)。SEQ = y
(B的初始序列号)
**第三次握手:**ACK=1 A确认B的请求。ACK = y + 1
(确认B的序列号)。SEQ = x + 1
四次挥手
第一次挥手:FIN = 1 A数据已发送完毕,请求关闭A->B的连接
第二次挥手:ACK = 1 B收到A的关闭请求,发送确认。此时,B->A的连接仍可传输数据
第三次挥手:FIN = 1 B数据也发送完毕,请求关闭B->A的连接
**第四次挥手:**ACK = 1 A收到B的关闭请求,发送确认
**挥手完成后:**连接终止,双方释放资源
在连接的建立过程中主机A和B也会有相应的状态变化,以下是二者的状态变化的过程:
1.三次握手阶段
对于客户端: 首先是在CLOSED状态开始,发送SYN包后进入SYN_SENT(已发送连接请求,等待确认)
对于服务端:首先是在CLOSED状态开始,并进入LISTEN(监听端口,等待连接请求)
当客户端收到SYN-ACK包,发送ACK包,进入ESTABLISHED状态(连接已建立,可以进行数据传输)
服务端收到ACK包后,也进入ESTABLISHED
2.数据传输阶段
此时二者都处于ESTABLISHED状态下进行数据的发送和接收
3.连接终止阶段
这是正常关闭连接的过程。注意:双方都可以主动发起关闭。
假设客户端先发起关闭:
主动关闭方 (Client)
- 发送FIN包后,从 ESTABLISHED 进入 FIN_WAIT_1 状态(已请求终止连接,等待确认)。
- 收到服务端的ACK后,进入 FIN_WAIT_2 状态(已得到终止确认,等待对方发送FIN包)。
- 收到服务端的FIN包后,回复ACK,进入 TIME_WAIT 状态(等待一段时间(2*MSL)以确保对方收到ACK,防止包丢失)。经过等待时间后,最终回到 CLOSED 状态。
- MSL是任何IP数据包在网络中存活的最大时间
被动关闭方 (Server)
- 收到FIN包后,从 ESTABLISHED 进入 CLOSE_WAIT 状态(已收到关闭请求,等待本地应用程序关闭)。
- 当应用程序调用close()后,发送FIN包,进入 LAST_ACK 状态(已发出最终终止信号,等待最后一个ACK)。
- 收到客户端的最后一个ACK后,连接结束,回到 CLOSED 状态。
3.1 三次握手和四次挥手的作用
方面 | 三次握手 | 四次挥手 |
---|---|---|
目的 | 建立可靠双工连接 | 终止可靠双工连接 |
核心作用 | 1. 验证连通性 2. 同步序列号 | 1. 可靠关闭(防丢包) 2. 允许数据收尾 |
设计关键 | 最短次数保证安全建立 | 必要次数保证完全关闭 |
状态特点 | 过程快速 | 存在等待(如TIME_WAIT ) |
3.2 连接失败的情况
控制标志中的RST就是运用在连接失败的这个情况中的,当一台主机收到一个不属于任何有效连接(异常报文,请求到不存在的端口之类的)的TCP报文时,这个主机就会回复RST(意味着“死刑”,不会自动重新建立连接,如果要重新建立连接就要重新“三次握手”)给对方主机作为响应,这个回复的过程是主机的TCP/IP协议栈(操作系统内核) 自动完成的,无需应用程序干预。
**时间差:**由于在主机回复RST的时间中,对方主机暂不知道RST所以会继续发送报文,而发送的RST会忽略这些报文或再触发一次RST,但这通常不会造成太大的影响
3.3 丢包
当主机A没有收到主机B发送过来的ACK包,就意味着发生了丢包
丢包分为两种情况:
1.主机A发送给主机B的数据包丢失了,导致主机B没有收到数据包从而无法发送ACK包
2.主机B发送给主机A的ACK包丢失了
如何解决丢包情况?
当超过一定时间(RTO(超时时间)=平均往返时间+4*往返时间波动值,平均往返时间和往返时间波动值都是跟网络有关的)主机A没有收到ACK包,主机A就会再发送一遍数据包,如果是数据包的丢失,那么这样就直接解决了,如果是ACK包的丢失,主机B会根据序列号判断收到了重复的数据包,然后把这个包丢弃,并再发送一次ACK包
4.滑动窗口
滑动窗口是一种流量控制与可靠性的机制,该窗口定义了当前允许连续发送但还未确认的数据范围
滑动窗口的存在是为了解决以下的问题:
- 流量控制:控制发送方的速度,防止发送过快导致接收方缓冲区溢出。
- 提高效率:允许发送方在未收到确认(ACK)前连续发送多个数据包,充分占用网络带宽,避免“发一个等一个”的低效模式。
以下是滑动窗口作用的过程:
首先分主机A和B,主机A是发送方,主机B接收方,在完成三次握手后,主机A根据在三次握手阶段收到主机B发送过来的ACK来决定发送给主机B的数据大小,然后主机B收到数据后向右调整窗口(这里就是滑动窗口),然后发送ACK给主机A,主机A根据ACK中的窗口信息从而决定发送多少数据给主机B
滑动窗口的start = 报文的确认序号
滑动窗口的end = start + win(对方的接受能力)
如果存在报文丢失的情况滑动窗口怎么办?
此时滑动窗口会停止向右滑动,TCP根据重传机制(超时或快速)来修复这个丢失的报文,一旦该报文被确认,窗口的左边界就能得以推进,整个窗口就可以继续向前滑动,传输得以恢复正常。