三次握手四次挥手
# 三次握手四次挥手
# 三次握手
Client给Server发送报文,Server知道自己能接收到Client发送的报文
该报文的SYN = 1, seq = x
Server给Client发送报文,Client知道自己能接收Server发送的报文,知道自己发送的报文能被Server接收
该报文的SYN = 1, ACK = 1,确认号 = x + 1, seq = y
Client给Server发送报文,Server知道自己发送的报文能被Client接收。
该报文的ACK = 1,确认号 = y + 1
经过三次握手,客户端(Client)和服务端(Server)都知道自己发送的报文能被对方接收,也知道自己能接收到对方的报文。
注:SYN / ACK / FIN 为TCP报文头部的一个标识。seq为报文的序列号(Sequence number),ack为报文的确认序号(并不是之前那个标识,而是Acknowledgement Number)。
SYN = 1,seq = x 对应的是 ACK = 1,ack = x + 1
为什么不两次握手
主要是为了防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
假设有这样一种场景, 客户端发送的第一个请求连接并且没有丢失,但是被滞留的时间太长。由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送报文。 而现在第一个请求到达服务端,这个请求已经报废了,但是又会建立连接。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
为什么不四次握手
既然三次就可以了,多一次就是浪费资源了。
# 四次挥手
TCP 是全双工的,在断开连接时两端都需要发送 FIN 和 ACK。
- 第一次挥手
- 若客户端 A 认为数据发送完成,则它需要向服务端 B 发送连接释放请求。
- 第二次挥手
- B 收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,表示 A 到 B 的连接已经释放,不接收 A 发的数据了。但是因为 TCP 连接时双向的,所以 B 仍旧可以发送数据给 A。
- 第三次挥手
- B 如果此时还有没发完的数据会继续发送,完毕后会向 A 发送连接释放请求,然后 B 便进入LAST-ACK状态。
- PS:通过延迟确认的技术(通常有时间限制,否则对方会误认为需要重传),可以将第二次和第三次握手合并,延迟 ACK 包的发送。
- 第四次挥手
- A 收到释放请求后,向 B 发送确认应答,此时 A 进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有 B 的重发请求的话,就进入 CLOSED 状态。当 B 收到确认应答后,也便进入 CLOSED 状态。