TCP三握手与四次挥手
# TCP三握手与四次挥手
# 三次握手
# 过程
- 客户端向服务端发送连接请求的SYN报文
SYN seq = x
- 服务端收到后,即可确认客户端的发送能力,并回复ACK报文
ACk seq=y, ack=x+1
- 客户端收到后,即可确认双方的收发能力,但此时服务端不确定自己的发送能力和客户端的接收能力。因此客户端回复一个ACK报文
ACK seq=x+1, ack=y+1
至此,双方都确认了彼此的收发能力,握手完成。
# 为什么不能是两次握手
如果是两次握手,即只要服务端收到来自客户端的SYN报文就建立连接。
如果客户端初始的SYN报文在网络中滞留,TCP会认为是丢包并进行重传。
因此,如果当前连接断开后,这个滞留的报文到达了服务端,则会建立起连接,而此时显然是一种资源的浪费。
# 快速打开TFO
利用SYN Cookie技术,收到客户端SYN报文后,计算出一个cookie值并保存。首次连接的三次握手照常进行
在后续连接中,服务端收到客户端请求后校验cookie值,若合法则在返回ACK报文后,即可开始传递数据,免去了等待客户端ACK报文的时间
# 四次挥手
# 过程
- 由客户端发起,首先发送一个FIN报文。此时,客户端不能再发送数据,只能接收
FIN seq=x
- 服务端收到后,马上返回一个ACK报文,并继续数据传输
ACK ack=x+1
- 当服务端传输完剩余数据后,发送一个FIN报文,表示数据传输完成
FIN seq=y
- 客户端收到后,返回一个ACK报文。
ACK ack=y+1
之后:
- 服务端收到ACK报文后马上进入关闭状态
- 客户端在等待2个
MSL(Maximum Segment Lifetime,报文最大生存时间)
后,若没有收到重传请求,则进入关闭状态
# 为什么不是三次挥手
服务端返回的ACK报文和FIN报文之间一般是有一定的延迟的,因为需要先将数据全部发送。
若将这两步合并,客户端迟迟没有收到回应的FIN报文,可能会认为是自己的ACK报文丢包,从而不断进行重传。
# 等待2MSL的意义
客户端发送ACK报文时,服务器端返回的数据可能还在网络中没有到达,此时若直接关闭连接,则可能造成丢包。
- 第一个MSL内,保证所有数据到达客户端
- 第二个MSL内,保证若有重传请求,可以到达客户端