通过TCP/IP协议的学习,我们可以知道TCP协议是一种面向连接的、可靠的传输协议。其中,为了保证客户端与服务器连接的有效性,就有了本篇文章所要介绍的“三次挥手”;而“四次挥手”则是为了保证连接的正确断开。
首先,介绍一下TCP的几个状态:
建立TCP连接时会经过如下步骤:
被动打开
主动打开
,并发送SYN(syn = i)
包,告诉服务器发送数据的序列号SYN(syn = j)
,其中含有服务器发送数据的初始序列号。注:SYN
和ACK
是同时发送的,在一个数据包中ACK(ack = j+1)
数据包其中,因为SYN需要占据一个字节的序列号空间,因此ACK中确认号为发来的SYN序列号加1;类似,FIN的ACK确认号为该FIN序列号加1。
主动关闭
被动关闭
。进行确认(ACK, ack = i+1),在该进程接收的其他所有数据之后添加文件结束符(end-of-file)建立连接时,因为发起连接的一端在发出请求后,连接建立之前,就不会再发出任何数据,因此接收连接请求的对端可以将ACK、SYN放在一个数据包里发回给请求端,即需要三次数据发送。而断开连接时,在一端主动断开连接并发送FIN包后,对端接收到发来的FIN包,进行确认(ACK),然而此时服务器可能还在给另一端发送数据,只有在数据发送完后才能断开连接,发送FIN包(所以不能像三次握手时那样将ACK、SYN同时发送),另一端收到FIN后再进行确认并发送ACK,因此需要四次数据发送。
TCP建立的连接为全双工通道,可以双向传输数据,因此在建立连接、断开连接时,需要两端都要进行请求与确认。
为什么建立连接的ACK、SYN可以同时发送,而断开连接则需要分开发送?
建立、断开连接都需要两次请求与确认,只是建立连接时SYN、ACK可以同时发回,而在断开连接时,由于被动关闭的一端可能还会发送数据,只有数据发完后才能发送ACK,所以只能分开发送,也就造成了建立连接为三次,断开连接反而成了四次。(建立连接时由于握手期间连接未完全建立,故不能发送其他数据)