TCP三次握手和四次挥手,中间失败了会发生什么?

我们都知道TCP建立连接时是三次握手,四次挥手,那么如果中间失败的话会发生什么?

三次握手:

在这里插入图片描述

第一次握手丢失了,会发生什么?

当客户端和服务器建立连接的时候,首先会发生一个SYN报文(第一次握手),然后
进入到SYN_SENT状态,假如说SYN丢失的话,即此时客户端一直收不到服务端SYN-ACK
报文(第二次握手),就会触发重传机制,重传SYN报文,而且重传的SYN报文的
序列号都是一样的。

在Linux中,客户端的SYN报文最大重传次数存储在tcp_syn_retries中
在这里插入图片描述
通常第一次重传是在1秒后,之后为2秒,等到第6次超时重传后,会等待64秒,如果依然没有收到服务端发送的SYN-ACK,则会断开连接。

第二次握手丢失后,会发生什么?

第二次握手就是服务器给客户端回复的SYN-ACK的过程,此时服务端会进入SYN_RCVD状态。

第二次握手的报文中包含对客户端的第一次ACK的确认报文,如果客户端没有收到服务端发送的SYN-ACK的话,则会以为自己发送的SYN丢失,则会继续重传SYN

而第二次握手的报文中还包含服务端发送给客户端的SYN,当服务端发送完SYN-ACK后,则会等待接收客户端发送的ACK,因为SYN-ACK丢失了,收不到ACK,所以此时服务端会意识到自己发送的报文丢失了,则会重传SYN-ACK

SYN-ACK的重传次数存储在tcp_synack_retries中
在这里插入图片描述

1. 对于客户端来说: 当客户端重传次数超过tcp_syn_retries时,再等待一段时间,如果还没有收到服务端的第二次握手,则会断开连接。

2.对于服务端来说: 当服务端重传次数超过tcp_synack_retries时,再等待一段时间,如果还没有收到客户端的第三次握手,则会断开连接。

第三次握手丢失了,会发生什么?

客户端收到服务端的SYN-ACK报文后,就会给服务端发送一个ACK报文(第三次握手),此时客户端进入到ESTABLISH状态。

因为第三次握手的ACK是对第二次握手的SYN的确认报文,所以当第三次握手丢失之
后,服务端接收不到客户端发送的ACK,就会以为发送的SYN-ACK丢失了,就会触发
超时重传机制,重传SYN-ACK,之后过程与上面一样。

四次挥手:

可以是服务端方主动发出的,也可以是客户端方主动发出的。

下面是客户端主动关闭连接。
在这里插入图片描述
以下都是对于此图(即客户端主动关闭连接)

第一次挥手丢失了,会发送什么?

 当客户端调用close()函数后,就会向客户端发送FIN报文,假如当这个FIN报文丢失
 了之后,那么客户端将会收不到服务端发送的ACK,则会触发重传机制,重传FIN,
 而重传次数存储在tcp_orphan_retries中。

在这里插入图片描述
当客户端重发的次数超过tcp_orphan_retries后,就会等待一段时间(此过程与上面将的一样),如果还没有收到ACK,则客户端就会断开连接。

此时我的tcp_orphan_retries的值为0,则它不会重传,则会直接断开连接。

第二次挥手丢失了,会发生什么?

当服务端收到客户端发送的FIN后,就会回复一个ACK(第二次挥手)。此时服务端就会进入到CLOSE_WAIT状态。

假如这个ACK丢失了,客户端就会以为自己发送的FIN报文丢失了,便会触发超时重
传机制,进行重传,此时,重传次数和第一次挥手的重传次数,都是同一个变量,保
存在tcp_orhan_retries中。

假如说超过重传次数后,还没有收到服务端的第二次挥手,那么客户端就会断开连接。

第三次挥手丢失了,会发生什么?

当第二次挥手后,服务端处于CLOSE_WAIT状态,通它此时会等待进程调用close关闭连接,当服务端调用了close之后,内核就会发送FIN报文(第三次挥手),同时进入LAST_ACK状态,等待客户端返回ACK来确认关闭连接。

假如说这个FIN丢失了,那么它此时一直收不到客户端发送的ACK,它此时就会触发
重传机制,重传FIN报文,重传次数依然由tcp_orphan_retries控制。

1.对于服务端来说 : 假如一直丢失FIN,当超过重传次数后,服务端一直接收不到客户端发送的ACK(即第四次挥手),此时服务端就会断开连接。

2.对于客户端来说 : 因为客户端此时处于FIN_WAIT_2状态,这个状态是有时间限制的,为tcp_fin_timeout时间,超过这个时间,还没有收到服务端发送的FIN,而它就会断开连接。

第四次挥手丢失了,会发生什么?

当客户端收到服务端发送的FIN报文后,就会回复ACK报文(即第四次挥手),此时客户端就会进入TIME_WIAT状态。

 假如说ACK报文丢失了,服务端一直收不到ACK,则会认为自己发送的FIN丢失了,
 则会重新发送FIN,重发次数仍然是tcp_orphan_retries。

在Linux系统中,TIME_WAIT状态会持续2MSL (2倍的MSL ,报文最大生存周期的两倍):网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理之后又会向对方发送响应,所以一来一回最大的时间是2倍的MSL。

根据上面所说,这也是为什么需要TIME_WAIT的原因。

假如说没有TIME_WAIT的话,当第四次挥手丢失之后,服务端重新发送FIN ,而此时发送过来后,已经没有人来处理这个报文了,所以需要TIME_WAIT状态。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值