详情来自:https://blog.csdn.net/qq_38182125/article/details/88883744
第一次握手:客户端向服务器发送连接请求报文,连接请求报文SYN=1,seq=x(x为计算机生成的随机数)。客户端进入SYN-SENT状态。TCP规定SYN报文段不能携带数据,但是要消耗掉一个序号。
第二次握手:服务端收到连接请求后,向客户端发送确认报文。SYN=1,ACK=1,(确认号)ack=x+1,(序号)Seq=y(y为服务端初始化序列号)。发送报文后服务端进入SYB-RCVD状态。此报文也不能携带数据,但要消耗一个序号。
第三次握手:客户端在收到服务器发送来的确认报文后,还需要向服务器发出确认。确认报文ACK=1,ack=y+1,seq=x+1。TCP连接建立客户端进入ESTABLISHED(establised)状态。TCP规定,ACK报文段可以携带数据,但是不携带数据不消耗序号。
为什么进行三次握手,两次不可吗?
如果只进行两次握手,客户端向服务器发送请求连接报文,服务器收到请求报文后,向客户端发送确认报文,此时服务器便认为连接已经建立,但数据在传输的过程中丢失,客户端就会认为自己尚未与服务端建立连接,进行重传,如果服务端发送的数据一直丢失,而客户端一直进行重传,服务器就会产生多个无效连接,占用资源,这个时候服务器可能会挂掉。而加入第三次握手后,服务器在第二次收到客户端发送的报文后才认为建立连接,就可避免上述问题。
如果已经建立了连接,客户端突然出现故障怎么办?
设置一个保活计时器,时间为2小时。每次服务端接收到客户端的报文后都会重置这个计时器。超过2个小时,服务器每隔75s向客户端发送探测报文,若一连发送10次任没反应,服务器就会认为客户端发生故障,关闭连接。
第一次挥手:客户端向服务器发出释放报文,并且停止发送数据。释放连接报文首部FIN=1,seq=u(等于前面已经穿送过来的数据的最后一个字节序号加1)。Tcp规定,FIN即使不携带数据也消耗掉一个序号。
第二次挥手:服务器收到客户端发送的释放连接报文后,向客户端发送一个确认报文。ACK=1,ack=u+1,seq=v(自己的序号),进入CLOSE-WAIT状态。客户端收到确认报文后,客户端进入FIN-WAIT-2状态,等待服务器向其发送释放连接报文,在收到释放连接报文前,客户端可能收到服务端向其发送的数据。
第三次挥手:在服务器没有数据需要发送给客服端时,服务器向客户端发送释放连接报文。FIN=1,ACK=1,ack=u+1,seq=w(服务器自己的序号),然后服务器便进入LAST-ACK状态。
第四次挥手:客户端在收到服务器的释放连接报文之后,向服务器发送确认报文ACK=1,ack=w+1,seq=u+1,进入TIME-WAIT状态该状态持续2msl,该时间过去后客服端进入CLOSED状态。
为什么释放连接的时候需要4次,而建立连接的时候需要3次?
因为释放连接需要经过双方的同意。头两次挥手的原因是客户端没有想服务器发送的数据了,所以客户端想要与服务器断开连接。断开的是客服端向服务器的通信方向。
客户端没有数据向服务端发送,不代表服务端没有数据向客户端发送。等到服务端也没有数据向客户端发送,客户端才向客户端发送释放连接报文,关闭彼此之间的连接。
在第四次挥手后,客户端为什么等待2MSL?
为了防止服务器没有收到第四次挥手的确认报文。
原文:https://www.cnblogs.com/jinkaijie/p/12483563.html