- 三次握手:
如下图所示:
刚开始时,服务器处于监听状态。
第一次握手:首先客户端向服务端发起请求,报文收不同部位SYN=1,并且选择初始序列号,seq=x,此时客户端进入SYN-SENT状态。需要消耗yige
第二次握手:服务器接到客户端连接请求后,若同意连接,则发送确认报文。ACK=1,SYN=1且确认号acq=x+1,并且给定一个初始序号,服务器进入SYN-RCVD状态。
第三次握手:客户端发送确认报文,ACK=1,seq=x+1,ack=y+1,客户端进入ESTABLISHED状态服务器收到确认报文后也进入ESTABLISHED状态。。
- 为何说呢么要发送最后一次确认?
假设没有第三次握手,可能会出现这样的情况,客户端发送了一次请求后并没有丢失,而是在网络节点中滞留的时间太长。客户端长时间没有收到服务器的确认报文,就会重新再发送第二次请求,并且第二次请求成功与服务器简历连接,此时第一次请求到达服务器端,服务器收到请求报文后又发一次确认请求则又建立一次不必要的连接,造成了资源的浪费。有了第三次握手之后,就算当收到第一个请求的服务器确认报文时,客户端便不会再次确认。服务器收不到确认报文,自然也不会建立连接。总之,发送最后一次确认的目的就是为了防止已经失效的请求报文突然又送到服务器造成错误。
- 四次挥手
如下图所示:
第一次挥手:客户端数据传输完毕后,主动发送连接释放报文。FIN=1,序列号seq=u(前面已经穿送过来的数据的最后一个字节的序号+1),进入等待状态1。
第二次挥手:服务器发送确认报文,同意释放连接。ACK=1,ack=u+1,并带上序列号seq=v,服务器进入CLOSE-WAIT状态。此时连接处于半关闭状态,即客户端向服务端的连接关闭,但服务器仍然可以往客户端传输数据。客户端收到确认请求后,进入等待状态2,等待服务器传输剩下的数据后的连接释放报文。
第三次挥手:服务器数据传输完毕后,向客户端发送连接释放报文FIN=1,ACK=1,序列号seq=w,ack=u+1,服务器进入LAST-ACK状态。
第四次挥手:客户端发送确认报文,ACK=1。ack=w+1,seq=u+1,服务端进入2MSL时长的等待状态,收到确认报文的服务器首先进入关闭状态。2MSL时长过后,客户端进入关闭状态,至此,连接释放。
本文图片来源:https://blog.csdn.net/qzcsu/article/details/72861891
-
为什么最后客户端要等待2MSL?
第一,为了保证最后一次确认请求能够正常到达服务器端,因为这个ACK可能丢失。
第二,使有足够的时间让旧连接的失效请求报文再网络中消失,不会出现在新的连接中。 -
为什么释放连接要四次挥手?
客户端是主动释放,在发送释放连接请求报文的时候说明客户端已经将所有的数据发送完毕;而服务器端不一样,是被动释放连接,此时服务器端可能还没有发送数据完毕,因此先发送确认请求让客户端单方面关闭连接,然后再进行剩余数据的传输,传输完成后再通知客户端释放连接,所以才多了一次挥手。