首先,TCP是面向连接的,所有在连接前要首先确保网络的通信
和双方的接收与发送数据
是否都正常。实质上就是连接服务器的指定端口,建立TCP连接,并同步双方的序列号和确认号,开始交换信息。
刚开始客户端属于关闭状态
,服务器端属于监听状态
第一次握手是客户端打开,然后向客户端发送SYN报文
,然后初始化自己的序列号。这时候客户端属于SYN_SENT
(报文发送状态)。
第二次握手是服务器端接收到客户端发送的SYN报文,然后以自己的SYN作为应答,发送给客户端,并且指定初始自己的序列号。同时会给客户端发送一个ACK报文(客户端的SYN+1
),表示自己已接收到客户端建立连接的请求。此时服务器端处于SYN_RCVD
(等待响应状态)。
第三次握手是客户端接收到来自服务器端的响应和SYN报文后,也会响应一个ACK报文
,表示已经接收到来自客户端的SYN报文,此时客户端处于ESTABLISHED
(可建立连接状态)。当服务器端收到ACK报文时,也会改为ESTABLISHED
(可建立连接状态)。此时双方开始正常通信。
建立连接需要三次握手,而终止一个连接要四次挥手。这是由于TCP的半关闭(half-clser)导致的,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
客户端发起关闭连接请求前,双方都处于ESTABLISHED
(连接状态)
第一次挥手是客户端会发送一个FIN报文
,保证中指定一个序列号。此时客户端处于FIN_WAIT1
(终止等待状态)。
第二次挥手是服务器端接收到来自客户端发送的FIN报文,服务器端发送ACK 报文
响应给客户端。此时服务器端处于CLOSE_WAIT
(关闭等待状态)。
第三次挥手 当服务器端的所有报文都发送完毕是,服务器端会给客户端发送FIN报文
,并且指定一个序列号。此时服务器端处于LAST_ACK
(最终确认状态)。
第四次挥手客户端收到服务器端发送的FIN报文后,一样会发送ACK报文作为应答,此时客户端处于TIME_WAIT
(时间等待状态),需要等服务器端收到ACK报文时后进入TIME_WAIT
(时间等待状态)。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
理论上,三次握手不能改为两次,因为三次握手的目的之一就是为了确认双方的接收和发送数据的能力
第一次握手是确认了客户端的发送和服务器端的接收
第二次握手是确认了服务器端的发送能力,此时服务器端并不能确认客户端有没有收到
!
第三次握手,服务端响应客户端发送的ACK报文,证明了客户端的接收正常。
在连接的时候,服务器端可以在收到客户端的请求后同时发送SYN+ACK报文。其中ACK作为应答,SYN作为同步。但是在关闭连接时,当服务器端收到FIN报文时,并不会立即关闭Socket,所以只能先恢复一个ACK报文,然后处理未发送完的报文。等服务器的全部报文发送完毕后,才能发送FIN报文,与客户端一起关闭。