这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战
6. TCP的运输连接管理
三次握手
1)、客户端主动打开,发送连接请求报文段,将SYN标识设置为1,sequence number设置为x(TCP规定SYN=1时不携带数据,x为随机产生的一个值),然后进入SYN_SEND状态;
2)、服务端接收到SYN报文段进行确认,将SYN标志位设置为1,ACK设置为1,sequence number设置为y,acknowledgment number设置为x+1,然后进入SYN_RECV状态,这个状态被称为半连接状态;
3)、客户端咋进行一次确认,将ACK设置为1(此时不用SYN),sequence number设置为x+1,acknowledgment number设置为y+1发向服务器,最后客户端与服务器都进入ESTABLISHED状态
四次挥手
1)、客户端发送一个报文给服务端(没有数据),其中FIN设置为1,sequence number设置为u,客户端进入FIN_WAIT_1状态;
2)、服务端收到来自客户端的请求,发送一个ACK给客户端,acknowledge设置为u+1,同时发送sequence number为v,服务端进入CLOSE_WAIT状态;
3)、服务端发送一个FIN给客户端,ACK设置为1,sequence 设置为w,acknowledge设置为u+1用来关闭服务器到客户端的数据发送,服务端进入LAST_ACK状态;
4)、客户端收到FIN后,进入TIME_WAIT状态,接着发送一个ACK给服务端,acknowledge设置为w+1,sequence number设置为u+1,最后客户端和服务端进入CLOSED状态。
常见问题
1)、建立连接是三次握手,两次可以吗?
client发送了第一个连接的请求报文,但是由于网络不好,这个请求没有立即到达服务端,而是在某个网络节点中滞留了,直到某个时间才到达server
本来这已经是一个失效的报文,但是server端接收到这个请求报文后,还是会想client发出确认的报文,表示同意连接。
假如不采用三次握手,那么只要server发出确认,新的建立就连接了,但其实这个请求是失效的请求,client是不会理睬server的确认信息,也不会向服务端发送确认的请求
但是server认为新的连接已经建立起来了,并一直等待client发来数据,这样,server的很多资源就没白白浪费掉了
采用三次握手就是为了防止这种情况的发生,server会因为收不到确认的报文,就知道client并没有建立连接。这就是三次握手的作用。
2)、为什么建立连接需要三次握手,断开连接需要四次挥手?
因为当server端收到client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当server端收到FIN报文时,很可能还有数据没有传送完成,并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,你的FIN报文我收到了。只有等到Server端所有的数据都发送完了,Server端才会发送FIN报文,因此不能一起发送。因此要四步分手。
3)、为什么TIME_WAIT状态需要经过2MSL(最大保温段生存时间)才能返回到COLSE状态?
A发送的确认释放连接信息B没有收到,这个时候B会再次发送一个FIN=1的释放连接请求,而这个时候A还处于TIME_WAIT,所以可以再次发送确认信息。
4)、如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果发生故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为两小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文,以后每隔75秒钟发送一次。若一连发送10个探测报文任然没有反应,服务器就会任务客户端出了故障,接着关闭连接。