TCP三次握手,四次挥手这是一个非常重要的知识点,我也来总结一下。
关于面试最经常问的问题无非就是:
- 握手为什么是3次? 2次可以吗? 为什么不是4次呢?
- 你能不能详细的介绍一下TCP三次握手的详细过程?
- 能不能说一下服务端和客户端在三次握手建立连接中的状态和行为?
- 挥手为什么是4次? 3次可以吗 ? (因为分开总比在一起难,哈哈)
- TIME_WAIT的作用? TIME_WAIT这个状态是保护谁??
关于以上的问题,下面都会详细讲解到。
TCP三次握手的过程
TCP的面向连接特性: ** 双方通信之前需要建立连接**
TCP是一种有状态的协议,必须确定双方在线且准备就绪之后才可以进行通信
每一个阶段的状态信息在图中已经大字号标注清楚。
握手为什么是三次?
因为两次不安全,四次没必要。 TCP是一个双工通信,需要双方都要确保对方具有数据收发能力。所以客户端得确定服务端是否在线,然后服务端也得确保客户端在线。SYN请求和ACK请求要一起发送,两个信息合成一个数据报一起发送给客户端就可以了,如果单独发,也可以,就没有必要。另外,若客户端发送SYN请求之后,万一退出了,这时候服务端不再进行一次确认的话,就会丢包。所以必须要有客户端最后一次发送ACK同意连接请求。综上,两次不安全,容易丢包。握手可以进行四次。但是没有必要。
四次挥手的过程
详细图解:
FIN包: 断开连接的请求 只是说明向对端不在写入数据了,但是还可以接收数据
挥手过程的过程(服务端与客户端状态的改变):
一开始主动关闭方(客户端)发送FIN包,表示要关闭套接字,不再进行向服务端写入数据。之后处于FIN_WAIT1状态。服务端接收到客户端的FIN包,知道是断开连接的请求,紧接着服务端进入CLOSED_WAIT状态。紧接着返回给客户端ACK,同意断开连接,客户端接收到ACK后,处于FIN_WAIT2状态。但是还有可能正在向客户端写入数据(返回数据)。所以等到服务端向客户端写入数据完毕,向客户端也发送一个FIN包,说明close()关闭套接字,或者关闭写操作,进入LAST_ACK状态(图中未标明)。客户端接收到FIN包,处于TIME_WAIT状态,然后再返回ACK。服务端接收到ACK后就进入CLOSED状态。而客户端的TIME_WAIT在等待两个MSL时长后,也进入CLOSED状态
挥手为什么是四次?
因为被动关闭方还有可能要发送数据,关闭方发送的FIN包只是说明了关闭方不再发送数据。服务端进行ACK回复之后,还有可能向客户端(主动关闭方)发送数据,只有当被动关闭方不再发送数据,关闭套接字之后,才会向客户端(主动关闭方)发送FIN包。所以ACK确认回复与FIN包不能一起发送。最终客户端(主动关闭方)收到最后的一个FIN包,再进行最后一次ACK回复,过程才结束。所以要进行四次通信联系。
TIME_WAIT的作用?
TIME_WAIT是为了保护主动关闭的一方,其实也就是保护客户端。因为服务端的地址信息从来就不会变。只有客户端的地址使用不了就会重新选择一个。
没有TIME_WAIT的话,主动关闭方的套接字直接被释放掉,新建立起的客户端有可能使用相同的地址和端口。这种情况下,最后一次的ACK丢失了,服务端会重新传这个FIN包,会对这个新起的客户端连接造成影响,如果新建立起的客户端向服务端发送一个SYN建立连接请求,但是服务端所处的状态时LAST_ACK状态(等待最后一次ACK响应的),服务端就不会认可这个SYN建立连接的请求。
简单的来说:TIME_WAIT是避免对新连接造成影响。
TIME_WAIT状态等待一段时间,等待两个MSL时间(报文最大生命周期),因为要等待的是FIN包和最后一次ACK的两个时间。