三次握手
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送syn 包(tcp 协议中syn位置1,序号为J)到服务器,并进入SYN_ SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的sYN,同时自己也发送一一个SYN包,即SYN+ACK包(tcp 协议中syn位置1,ack位置1,序号K,确定序号为J+1),此时服务器进入SYN RECV状态:
第三次握手:客户端收到服务器的SYN+ACK 包,向服务器发送确认包ACK (tcp协议中ack位置1,确认序号K+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。通过这样的三次握手,客户端与服务端建立起可靠的双工的连接,开始传送数据。三次握手的最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的。
但是为什么一定要进行三次握手来保证连接是双工的呢,一次不行么? 两次不行么?
我们举一个现实生活中两个人进行语言沟通的例子来模拟三次握手。同理对于TCP为什么需要进行三次握手我们可以一样的理解:为了保证服务端能收接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手,为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手。
四次挥手
由于ICP连接是全双工的,因此每个方向都必须单独进行关闭。这好比,我们打电话(全双工),正常的情况下(出于礼貌),通话的双方都要说再见后才能挂电话,保证通信双方都把话说完了才挂电话。
那TCP的四次握手,是为了保证通信双方都关闭了连接,具体过程如下:
1、客户端A在应用层调用close时会激发底层发送一一个FIN (tcp协议中FIN位置1、序号为M,结合上图分析)请求,用来关闭客户A到服务器B的数据传送,客户端A此时处于半关闭状态(应用层无法接收数据但底层还可以接收数据) :
2、服务器B底层收到客户端A的FIN时会做两件事
第1件事:收到客户端A的FIN时底层会主动回发一个ACK(tcp协议中ACK位置1,确认序号M+1)
第2件事:收到客户端A的FIN时,导致服务器B的应用层read()返回0 (告诉服务器B应用层:客户端A关闭了)
3、服务器B应用层调用close ()激发底层给客户端A发送一个FIN (tcp 协议中FIN位置1、序号为N) , 这是服务器B已处于半关闭状态;
4、客户端A底层回发ACK (tcp协议中ACK位置1,确认序号N+1)给服务器B, 这是客户端A、服务器B都处于完全关闭状态,回收相应的资源。
TCP 通信过程中各步骤的状态图 1
状态图 2
对于上面的图 N 多人都知道,它排除和定位网络或系统故障时大有帮助,但是怎样牢牢地将这张图刻在脑中呢?那么你就一定要对这张图的每一个状态,及转换的过程有深刻的认识,不能只停留在一知半解之中。下面对这张图的 11 种状态详细解析一下,以便加强记忆!不过在这之前,先回顾一下 TCP 建立连接的三次握手过程,以及关闭连接的四次握手过程,详情请看上面的 TCP 三次握手和四次挥手。