1、三次握手过程理解
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
上面这样描述三次握手可能有些人看不懂,我就简单的情景化一下:
这里有俩对象,一个是客户端,一个是服务器端,他俩的目的是建立连接。首先,客户端发送一个同步序列编号(syn包),问:“服务器,你能听到我说话吗?”,等待服务器确认。然后,服务器收到syn包后,服务器发送一个自己的syn和ack包,给客户端说:“客户端,我能听到了”。最后,客户端收到服务器的syn+ack包后,向服务器端发送一个ack确认包,说:“好的,那我们可以开始聊天了”。
2、四次挥手
由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
简单理解四次挥手:客户端给服务器端发送一个FIN,相当于说:“好了,下次再聊”,等待服务器回答。服务器收到FIN后,发送一个ACk给客户端,说:“我知道了”。然后服务器端发送一个FIN,关闭服务器到客户端的数据传送。最后,客户端收到FIN后,接着发送一个ACK给服务器,相当于确认关闭了服务器和客户端的数据传送。
3、为什么连接的时候是三次握手,关闭的时候却是四次挥手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步挥手。