三次握手
- 第一次握手:客户端向服务器发送一个连接请求报文,这个报文的首部里SYN标志位被置为1,这时客户端就进入SYN_SENT状态。
- 第二次握手,当服务器收到客户端发送的连接请求报文后,如果服务器同意建立连接,则会发送一个确认报文,该确认报文里面SYN和ACK标志位都被置为1,这是服务器就进入SYN_RECVD状态。
- 第三次握手:当客户端收到服务器发来的请求确认报文,客户端就向服务器发送一个确认报文,里面ACK标志位被置为1,这时客户端连接建立成功,客户端进入ESTABLISHED状态,当服务器收到客户端发来的确认报文,服务器认为连接已经建立成果,服务器也进入ESTABLISHED状态。
通俗理解【我们以男女处对象为例】:
第一次握手:男生说你好漂亮我很喜欢你
第二次握手:女生说你也不错我也欣赏你
第三次握手:男生说那我们就成为情侣了
看到这里,你或许会问,那么为什么需要第三次握手呢?我们来看一下,假设一下如果没有第三次握手,而是两次握手后我们就认为连接成功了,那么会发生什么?第三次握手是为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误。
譬如发起请求遇到类似这样的情况:客户端发出去的第一个连接请求由于某些原因在网络节点中滞留了导致延迟,直到连接释放的某个时间点才到达服务端,这是一个早已失效的报文,但是此时服务端仍然认为这是客户端的建立连接请求第一次握手,于是服务端回应了客户端,第二次握手。
四次挥手
- 第一次挥手:当客户端没有任何数据向服务器发送时,客户端主动断开连接。客户端发送一个请求断开连接的报文,里面FIN标志位被置为1,这是客户端就进入FIN_WAIT1状态。
- 第二次挥手:当服务器收到客户端发送来的请求断开连接的报文,服务器会对该报文进行确认,就会发送一个确认报文给客户端,该报文的ACK标志位被置为1,这时服务器就进入CLOSE_WAIT状态。当客户端收到服务器发来确认报文后,客户端就进入FIN_WAIT2状态,此时客户端到服务器的通道就被关闭,客户端不能向服务器发送数据,但是,服务器到客户端的通道并没有关闭,服务器仍然可以向客户端发送数据,客户端也会对发来的数据进行确认,此时就处于半关闭状态。
- 第三次挥手:当服务器不用向客户端发送数据的时候,服务器就会向客户端发送一个请求断开连接报文,表示服务器到客户端的通道也要关闭了,这时服务器就进入LAST_ACK状态,等待最后一个ACK的到来。
- 第四次挥手:当客户端收到服务器发来的请求断开连接报文后,客户端会向服务器发送一个确认报文,随即进入TIME_WAIT状态,并且会等待2MSL(MSL:最大报文生存时间),如果在2MSL里面服务器没有收到客户端发来的ACK,那么服务器就会重新发送一个FIN报文,此时客户端又会发送一个ACK报文并会重新等待2MSL.如果服务器收到客户端发送的ACK报文,此时服务器就会进入CLOSED状态,2MSL之后,客户端也进入CLOSED状态。可以看到服务器比客户端先进入CLOSED状态。
(注意:四次挥手过程中的第二次挥手说了客户端到服务器的通道就被关闭,客户端不能向服务器发送数据,但是在第四次挥手又说当客户端收到服务器发来的请求断开连接报文后,客户端会向服务器发送一个确认报文,我的理解是数据通道关闭了,命令通道并没有关,也就是说下图里面的TCP首部可以传,TCP数据部分不能传了)
通俗理解【男女分手为例】:
第一次挥手:男生说你这个人不咋地,我们分手吧
第二次挥手:女生说渣男,分手就分手
第三次挥手:女生说这是你给我的东西,现在全部还给你
第四次挥手:男生说好的,我拿走,再见
为什么挥手要四次:我的理解是主要在第三次挥手,服务端并不能立即把通道关闭,要等到把数据全部给完客户端才能关闭
TCP连接状态解释
- CLOSED:关闭
- SYN_SENT:同步发送
- SYN_RECVD:同步接收
- LISTEN:监听
- ESTABLISHED:已建立连接
- FIN_WAIT:终止等待
- CLOSE_WAIT:关闭等待
- TIME_WAIT:时间等待
参考文章:
baijiahao.baidu.com/s?id=165422…