TCP三次握手
第一次握手:客户端发送第一个包,其中SYN标志位为1, ACK=0,发送顺序号sequence=X(随机int)。客户端进入SYN发送状态,等待服务器确认。
第二次握手:服务器收到这个包后发送第二个包,其中包SYN、ACK标志位为1,发送顺序号seq=Y(随机int),接收顺序号ACK=X+1,此时服务器进入SYN接收状态。
第三次握手:客户端收到服务器传来的包后,向服务器发送第三个包,SYN=0, ACK=1,接收顺序号ACK = Y+1,发送顺序号seq=X+1。此包发送完毕,客户端和服务器进入ESTABLISHED建立成功状态,完成三次握手。
-
SYN(synchronous建立联机)
-
ACK(acknowledgement 确认)
-
PSH(push传送)
-
FIN(finish结束)
-
RST(reset重置)
-
URG(urgent紧急)
-
Sequence number(顺序号码)
-
Acknowledge number(确认号码)
-
establish 建立,创建
四次挥手
-
第一次挥手:当客户端的数据都传输完成后,客户端向服务端发出连接释放报文(当然数据没发完时也可以发送连接释放报文并停止发送数据),释放连接报文包含FIN标志位(FIN=1)、序列号seq=u,其中的1是建立连接时占的一个序列号)。需要注意的是客户端发出FIN报文段后只是不能发数据了,但是还可以正常收数据;另外FIN报文段即使不携带数据也要占据一个序列号。
-
第二次挥手:服务端收到客户端发的FIN报文后给客户端回复确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=1+u、序列号seq=v。此时服务端处于关闭等待状态,而不是立马给客户端发FIN报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完。
-
第三次挥手:服务端将最后数据(比如50个字节)发送完毕后就向客户端发出连接释放报文,报文包含FIN和ACK标志位(FIN=1,ACK=1)、确认号和第二次挥手一样ack=1+u、序列号seq=w。
-
第四次挥手:客户端收到服务端发的FIN报文后,向服务端发出确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=1+w、序列号seq=1+u。注意客户端发出确认报文后不是立马释放TCP连接,而是要经过2MSL(最长报文段寿命的2倍时长)后才释放TCP连接。而服务端一旦收到客户端发出的确认报文就会立马释放TCP连接,所以服务端结束TCP连接的时间要比客户端早一些。
面试题常问:
1、为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
建立连接时,ACK和SYN可以放在一个报文里来发送。而关闭连接时,被动关闭方可能还需要发送一些数据后,再发送FIN报文表示同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
2、如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP设有一个保活计时器,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。