TCP三次握手
所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。整个流程如下图所示:
- 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
- 第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server同意建立连接,将标志位ACK置为1,保存client的seq(J),ack=J+1;将标志位SYN置为1,随机产生一个值seq=K,将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
- 第三次握手:Client收到确认后,检查ACK是否为1,ack是否为J+1,如果正确则将标志位ACK置为1,ack=K+1,seq=J+1,并将该数据包发送给Server,Client进入ESTABLISHED状态
- Server收到确认后,检查ACK是否为1,ack是否为K+1,如果正确,则连接建立成功,Server也进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
TCP四次挥手(Client或Server均可主动发起挥手动作)
所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。整个流程如下图所示:
- 第一次挥手:Client发送FIN=1,seq=M,请求关闭Client到Server的数据发送,Client进入FIN_WAIT_1状态。
- 第二次挥手:Server收到FIN后,发送一个ACK=1给Client,确认序号ack=M+1,Server进入CLOSE_WAIT状态。
- 第三次挥手:Server发送FIN=1,seq=N,ack=m+1,请求关闭Server到Client的数据传送,Server进入LAST_ACK状态。
- 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK=1给Server,确认序号ack=N+1,Server进入CLOSED状态,完成四次挥手。
为什么连接的时候是三次握手,关闭的时候却是四次握手?
Server在LISTEN状态下,收到建立连接请求的SYN报文后,可以直接把ACK和SYN放在一个报文里发送给Client。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必将全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。
为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
- Client的最后一个ACK报文在传输的时候丢失,Server并没有接收到这个报文。这个时候,Server就会超时重传这个FIN消息,然后Client就会重新返回最后一个ACK报文,等待两个时间周期,完成关闭。如果不等待这两个时间周期,Server重传的那条消息就不会收到。Server就因为接收不到Client的信息而无法正常关闭。
- 防止“已失效的连接请求报文段”出现在本连接中。在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段,都从网络中消失。这样就可以使下一个新的连接中不会出现这种就得连接请求报文段。