三次握手
三次握手过程
- 第一次握手:客户端向服务端发起连接请求报文,报文的同步位SYN=1,序列号seq=x。客户端进入syn-sent状态。
- 第二次握手:服务端收到客户端的连接请求,会返回一个确认报文,报文的同步位SYN和确认位ACK等于1,确认号ack=x+1,序列号seq=y。服务端进入syn-revd状态。
-
第三次握手:客户端收到之后,也会返回一个确认报文,报文的确认位ACK=1,确认号ack=y+1,序列号seq=x+1。客户端进入连接状态,连接建立,服务端收到消息也会进入连接状态。
为什么要三次握手
- 两次握手无法确认客户端的接受能力是否正常,也就无法确认客户端收到了服务端的初始序列号,三次握手是可以确保的。
- 防止已经失效的连接请求到了服务器端,建立无效连接,浪费资源。比如客户端发起连接请求,出现网络超时,发生了重传,后面的连接请求和服务端建立了连接之后正常关闭,关闭之后,前面超时的连接请求又到了服务端,服务端就会进行确认再次进行连接,但是客户端还是关闭状态,如果是三次握手,就不会出现这种情况。
半连接队列
服务器第一次收到连接请求时,会处于syn revd状态,服务器会把这种状态的连接放到一个队列中,这个队列就叫半连接队列。建立连接之后就会把这个半连接移到全连接队列中。
四次挥手
四次挥手过程
- 第一次挥手:客户端数据处理完成,给服务端发送一个结束报文,报文中终止位FIN=1,序列号seq=u,客户端进入fin wait1状态。
- 第二次挥手:服务端收到之后,会返回一个确认报文,报文确认位ACK=1,确认号ack=u+1,序列号seq=v。服务端进入close wait状态。客户端收到之后进入fin wait2状态。
- 第三次挥手:服务端处理完数据之后,给客户端发送一个结束报文,报文中终止位FIN=1和确认位ACK=1,确认号ack=u+1,序列号seq=w。服务端进入last ack状态。
-
第四次挥手:客户端收到之后,会返回一个确认报文,报文中确认位ACK=1,确认号ack=w+1,序列号seq=u+1。客户端端进入time wait状态,等两个msl(报文最大生存时间)的时间就会进入close状态。服务端收到之后进入colse状态。
为啥要等待2msl
确保服务端连接正常关闭。如果服务端没有正常收到客户端的确认报文,就会重新发结束报文,2msl能确保服务端的重传报文被客户端收到。