和建立连接时的三次握手类似,三次握手建立连接的标识为SYN,四次握手终止连接的标识为FIN。由于TCP连接是全双工,所以发送了FIN的一端只是关闭了发送连接,但仍然可以接受数据。所以,若要彻底关闭连接,则需要双方都发送FIN。
还是通过实验来观察四次握手流程。当通过SSH软件输入exit命令时,客户端发出带FIN标识的TCP包:
服务器收到FIN后,发送一个ACK包,确认序号应该为收到的序号加1,
但这里并没有加1,因为服务器接紧接着会发送一个FIN,在那个FIN中再让确认序号加1
:
同时,服务器也会发送一个FIN给客户端,果然这里的确认序号为收到序号加1,由于单独的ACK包不消耗序号,所以此TCP包的序号和上一个相同:
客户端收到FIN后,再返回一个ACK包,确认序号为收到序号+1,FIN和SYN一样需要消耗一个序号,所以这里的序号相对于第一次握手还是增加了1:
至此,四次握手结束,TCP连接断开。注意,连接通常是由客户端发起,关闭连接两端都能主动关闭,但通常由客户端决定何时终止连接。
附带一张连接建立和连接终止的整体流程图:
参考:
《TCP/IP详解》 P177.