一、TCP建立连接的三次握手机制
1.TCP 3次握手建立连接
建立TCP连接:在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接:
- 建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
SYN:同步序列编号(Synchronize Sequence Numbers) - 服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
- 客户端收到服务器的SYN+ACK包(此时客户端进入ESTABLISHED状态),向服务器发送确认包ACK(ack=k+1),此包发送完毕,服务端收到这个包后进入ESTABLISHED状态,客户端和服务器都进入ESTABLISHED状态,完成三次握手。
三次握手的关键就在于,它可以应变连接请求是否失效。
三次握手建立连接的流程如下:
2.为什么需要第三次握手
需要第三次握手根本原因是防止失效的连接请求报文段被服务端接收,从而产生错误,具体表现:若建立连接只需两次握手,客户端并没有太大的变化,仍然需要获得服务端的应答后才进入ESTABLISHED状态,而服务端在收到连接请求后就进入ESTABLISHED状态。此时如果网络拥塞,客户端发送的连接请求迟迟到不了服务端,客户端便超时重发请求,如果服务端正确接收并确认应答,双方便开始通信,通信结束后释放连接。此时,如果那个失效的连接请求抵达了服务端,由于只有两次握手,服务端收到请求就会进入ESTABLISHED状态,等待发送数据或主动发送数据。但此时的客户端早已进入CLOSED状态,服务端将会一直等待下去,这样浪费服务端连接资源。
二、TCP关闭连接的四次挥手机制
1.TCP 4次握手关闭连接
对于一个已经建立的连接,TCP使用改进的三次握手来释放连接(使用一个带有FIN附加标记的报文段)。TCP关闭连接的步骤如下:
- 客户端向服务器发送一个带有FIN附加标记的报文段(FIN表示英文finish),客户端进入FIN_WAIT_1状态;
- Server收到FIN后,并不立即用FIN报文段回复客户端,而是先向客户端发送一个确认序号ACK,同时通知自己相应的应用程序:对方要求关闭连接(先发送ACK的目的是为了防止在这段时间内,对方重传FIN报文段),此时服务器进入CLOSE_WAIT状态;
- 服务器关闭与客户端的连接:当服务器发送的数据完成之后会单独向客户端发送一个FIN报文段,表示同意关闭连接;服务器进入LAST_ACK状态
- 客户端收到服务端的FIN报文段后,客户端进入TIME_WAIT状态,向服务端发送ACK表示连接彻底释放,服务端进入CLOSED状态,完成四次握手。
四次挥手关闭连接的流程:
2.为什么是四次挥手
因为TCP连接是双向连接的,即客户端会向服务端发送数据请求,服务端会向客户端发送响应的数据,TCP是一种可靠的连接方式。客户端发送完数据,服务端不一定把所有的响应数据发送完成,关闭连接时需要断开客户端向服务端发送数据的连接(此时客户端还可以接收服务端发送的数据)和服务端向客户端发送响应的连接,即服务端对客户端关闭连接的请求的响应ACK和服务端同意关闭连接的FIN字段需要分开发送。
PS:建立连接时的第二次握手时服务端向客户端发送的响应包括SYN和ACK。