12.TCP协议
# 01.TCP
- TCP协议是互联网最核心的通信协议之一
- 它工作在OSI模型的传输层,为应用程序提供可靠、面向连接的数据传输服务
- TCP能够确保数据包按照正确的顺序、无错误地传输到目的地
# 1、TCP的基本特点
- 面向连接:
- 在通信双方之间建立一个虚拟连接,确保双方能够进行可靠的数据传输
- 通信前必须先经过三次握手建立连接,通信结束后通过四次挥手释放连接
- 可靠传输:
- TCP通过确认机制、重传机制和错误检测保证数据传输的可靠性
- 全双工通信:
- TCP允许通信双方同时发送和接收数据,意味着在同一时间可以进行双向数据传输
- 有序传输:
- TCP确保数据包按照发送的顺序到达目的地,
- 即使在网络中某些数据包先到达,TCP仍会按照正确顺序交付数据
- 流量控制与拥塞控制:
- TCP通过流量控制和拥塞控制机制,防止网络过载以及接收方无法处理过多的数据
# 2、TCP报文结构
- TCP数据在传输时被封装成TCP报文段,其报文段的结构如下
- 源端口号(16位):标识发送数据的端口
- 目的端口号(16位):标识接收数据的端口
- 序列号(32位):
- 用于保证数据的有序性
- 每个TCP连接中的每个字节都有一个序列号,表示该段数据在整个数据流中的位置
- 确认号(32位):表示接收方期望收到的下一个字节的序列号,用于实现确认机制
- 数据偏移(4位):指示TCP报头的长度
- 保留位(6位):保留字段,暂时未使用
- 标志位(6位):用于控制TCP状态变化的几个重要标志位:
- URG:表示数据段中有紧急数据
- ACK:确认标志,表示确认字段有效
- PSH:表示接收方应立即将数据交付给上层应用,而不再缓冲
- RST:重置连接,出现错误时终止连接
- SYN:用于连接建立的同步标志
- FIN:表示发送方已经发送完毕,准备关闭连接
- 窗口大小(16位):用于流量控制,表示发送方能够接收的字节数
- 校验和(16位):用于检测传输过程中数据是否损坏
- 紧急指针(16位):指出紧急数据的结束位置
- 选项和填充:用于传输控制的额外信息,如MSS(最大报文段大小)等
- 数据:实际传输的数据内容
# 3、TCP的连接管理
# 1)三次握手
- TCP通过三次握手来建立连接,确保双方都准备好开始通信
SYN:
- 客户端发送一个SYN(同步)报文段给服务器,表示希望建立连接,并附带客户端的初始序列号
SYN-ACK:
- 服务器收到SYN报文段后,回复一个SYN-ACK报文段
- 表示同意连接,并附带服务器的初始序列号和对客户端SYN的确认
ACK:
- 客户端收到服务器的SYN-ACK后,发送一个ACK报文段,确认服务器的序列号,至此连接建立
# 2)四次挥手
FIN: 客户端发送一个FIN报文段,表示不再发送数据
ACK: 服务器收到FIN后,发送ACK报文,确认客户端的请求,但此时服务器仍可能有数据需要发送
FIN: 服务器发送完所有数据后,也发送一个FIN报文段,表示服务器也准备关闭连接
ACK: 客户端最后发送一个ACK,确认服务器的FIN,至此连接关闭
# 3)为什么挥手要四次
三次握手是为了确保双方能够建立一个可靠的连接,并且同步彼此的初始序列号
为什么是三次?
第一次握手:客户端告诉服务器“我要建立连接,我的序列号是X”
第二次握手:服务器回应“我收到了,我的序列号是Y,同时确认你X号收到了”
第三次握手:客户端再确认“我收到了你的确认,并确认你Y号”
为什么是四次?
第一次挥手:客户端告诉服务器“我不再发送数据了”
第二次挥手:服务器回应“我知道了,但我
可能还有数据要发,等我发完再告诉你
”第三次挥手:服务器发完数据后告诉客户端“我也不再发送数据了”
第四次挥手:客户端回应“我确认了”,并等待一定时间以确保没有丢失的报文
# 4、TCP的可靠性机制
# 1)序列号和确认号
- TCP使用序列号确保数据包按正确顺序传输
- 每个发送的数据段都会附带一个序列号,接收方根据这个序列号确认收到的包是否正确
- 确认机制:
- 接收方接收到数据后,会向发送方发送一个ACK报文,表明已经收到并期望接收的下一个字节
# 2)超时重传
- TCP会为每个发送的数据段设置一个计时器,如果在超时时间内没有收到ACK确认,TCP将重传该数据段
- 重传的次数通常是有限的,如果多次重传失败,连接可能会被关闭
# 3)错误检测
- TCP使用校验和来检测传输中的错误
- 发送方在发送数据时计算数据的校验和
- 接收方根据接收到的数据重新计算校验和
- 如果发现不匹配,则丢弃该数据段
# 5、TCP的流量控制
- 流量控制是为了防止发送方发送过多的数据,使接收方处理不过来
- TCP使用 滑动窗口机制 控制流量
- 每个TCP连接都有一个窗口大小,表示发送方在不收到确认的情况下可以连续发送的字节数
- 接收方通过在ACK报文中携带窗口大小来告诉发送方自己能够接收的最大数据量
- 当窗口大小变小,发送方必须降低数据传输速度,反之亦然
# 6、TCP的拥塞控制
- 拥塞控制是为了避免网络出现过载情况而设计的机制
- TCP通过四个算法来进行拥塞控制
① 慢启动(Slow Start)
- 在连接初始或重传超时后,TCP开始时发送数据的速率较慢
- 随着接收到ACK报文,逐渐增大发送速率
- 每次成功确认后,发送窗口的大小会加倍,直到达到一个阈值
② 拥塞避免(Congestion Avoidance)
- 当发送窗口达到阈值时,TCP进入拥塞避免阶段
- 每次成功确认只将发送窗口增加一个段大小,以避免过快增加导致网络拥塞
③ 快重传(Fast Retransmit)
- 当接收方发现有数据丢失时,会连续发送多个重复的ACK
- 发送方在收到3个相同的ACK时,会立即重传丢失的数据段,而不等待超时
④ 快恢复(Fast Recovery)
- 在快速重传后,TCP并不立即进入慢启动
- 而是通过快恢复算法继续控制拥塞窗口的增长,避免过于剧烈的传输速率变化
# 7、TCP与UDP的对比
特性 | TCP | UDP |
---|---|---|
是否面向连接 | 是 | 否 |
传输可靠性 | 可靠传输,确保数据无丢失、无错序 | 不保证可靠传输 |
流量控制与拥塞控制 | 有 | 无 |
适用场景 | 文件传输、邮件、网页浏览等需要可靠传输的场景 | 视频流、实时通信、游戏等需要快速传输的场景 |
# 02.常见问题
# 1、三次握手和四次挥手
- TCP的三次握手和四次挥手是什么?为什么需要?
- 三次握手用于确保客户端和服务端都能够正常接收和发送数据,同时允许双方协商初始的序列号
- 客户端发送SYN包,表示请求建立连接
- 服务端收到后,回复SYN-ACK包,表示接收请求并同意建立连接
- 客户端收到后,发送ACK包,确认连接建立
- 四次挥手用于安全、可靠地关闭连接,确保双方的数据传输完成
- 客户端发送FIN包,表示结束数据发送
- 服务端收到FIN后,回复ACK包,表示同意关闭
- 服务端也发送FIN,表示它的数据也传输完成
- 客户端回复ACK,最后连接关闭
为什么需要:
- 三次握手可以防止“旧连接请求”带来的误连接问题,同时协商序列号
- 四次挥手确保了双方都能有序、彻底地关闭连接,避免数据丢失
# 2、TCP如何保证可靠性
- 序列号:每个数据包都有序列号,确保数据按顺序接收
- 确认机制:接收方会发回ACK确认数据接收,发送方在超时未收到ACK时重传数据
- 流量控制:利用滑动窗口机制,发送方根据接收方的窗口大小控制发送速度,避免过载
- 拥塞控制:通过慢启动、拥塞避免、快速重传和快速恢复等机制,防止网络拥塞
- 重传机制:当发送的数据包丢失或损坏时,发送方会根据超时或接收方的重复ACK进行重传
# 3、TCP和UDP的区别
可靠性:TCP是可靠的连接,确保数据到达且无误;UDP是不可靠的,不保证数据到达
连接性:TCP是面向连接的,需要三次握手建立连接;UDP是无连接的,不需要握手
传输速度:UDP速度快,适合实时应用;TCP速度相对较慢,但更稳定
数据包大小:UDP的数据包较小,头部只有8字节;TCP头部较大,有20字节或更多
适用场景:
TCP:适合需要高可靠性的数据传输(如HTTP、FTP等)
UDP:适合对实时性要求高但允许部分数据丢失的场景(如视频会议、在线游戏等)
# 4、滑动窗口是什么
- TCP中的滑动窗口是什么?有什么作用?
滑动窗口是TCP流量控制的一部分,动态调整发送方的数据传输速率
窗口大小:接收方通过窗口大小告知发送方当前能接收的数据量,发送方在不超过窗口大小的情况下发送数据
作用:滑动窗口通过限制未确认的数据量,防止发送方传输过多数据造成接收方缓冲区溢出
# 5、TCP慢启动
慢启动是TCP拥塞控制的一个重要机制
原理:
- 刚开始连接时,TCP会以较小的速度发送数据
- 每次收到ACK后成倍增加发送速率,直到达到拥塞窗口的阈值(拥塞避免状态)
目的:防止突然大量数据传输导致网络拥塞,通过逐步增加发送速率来探测网络状态
# 6、处理网络中的丢包
- 超时重传:发送方设定超时时间,如果在规定时间内没有收到ACK,会重传数据
- 快速重传:
- 当接收方收到乱序数据时,会重复发送ACK
- 如果发送方收到三个相同的ACK(代表有数据丢失),立即重传丢失的数据包
# 7、拥塞控制
- 慢启动:初始发送速率低,逐步增加直到达到网络拥塞阈值
- 拥塞避免:超过阈值后,发送速率逐渐增加,而不是成倍增长
- 快速重传:接收到三个重复ACK时,立即重传丢失数据
- 快速恢复:在丢包后,发送速率从一个较高值重新开始,而不是从慢启动的初始值
# 8、粘包 现象如何处理
- 粘包现象:TCP是流式协议,数据没有明显的边界,多个数据包可能被合并到一起接收,造成接收方难以区分
- 处理方式:常见的处理方式包括:
- 固定长度包协议:规定每个包的固定长度
- 分隔符协议:在每个数据包之间加特定分隔符,如换行符
- 长度前缀协议:在数据包的头部加上长度信息,接收方根据长度解析