• 作者:老汪软件技巧
  • 发表时间:2024-08-28 15:02
  • 浏览量:

1. TCP的三次握手过程

开始客户端和服务器都处于CLOSED状态,然后服务端开始监听某个端口,进入LISTEN状态

2. 第三次握手没有回复,连接建立不了.

上个小节,我们梳理完TCP三次握手流程,也就是TCP需要三次握手,才能真正建立连接。

如果服务器没有收到客户端发送的第三次握手的ACK确认包,那么从服务器的角度看,这个连接仍处于未完全建立的状态,不能正式用于数据传输。

也就是如果没有第三次握手回复,只有两次握手,那是不行的。TCP连接,为什么需要三次握手,为什么两次不行,为什么四次不行?

为了方便理解,我们以谈恋爱为例子:两个人能走到一起,最重要的事情就是相爱,就是我爱你,并且我知道,你也爱我,接下来我们以此来模拟三次握手的过程:

为什么握手不能是两次呢?

如果只有两次握手,女孩子可能就不知道,她的那句我也爱你,男孩子是否收到,恋爱关系就不能愉快展开。

为什么握手不能是四次呢?

因为握手不能是四次呢?因为三次已经够了,三次已经能让双方都知道:你爱我,我也爱你。而四次就多余了。

3. 第三次握手没有回复,服务器会出现什么现象?

TCP三次握手:

服务器在收到客户端的 SYN 报文后,会发送一个 SYN-ACK 报文并进入 SYN-RECEIVED 状态。此时,它正在等待客户端发送的 ACK 报文。如果客户端的 ACK 报文没有到达服务器,服务器会在 SYN-RECEIVED 状态中停留一段时间(通常称为超时重传时间)。

也就是说,第三次握手没有ACK回复,服务器会在 SYN-RECEIVED 状态中停留一段时间。然后超时重传。

然后如果没有收到客户端的 ACK 报文,它会重新发送 SYN-ACK 报文。

当然,重试肯定有次数限制的,如果在重传了多次之后,服务器仍然没有收到客户端的 ACK 报文,服务器会认为连接失败,并放弃这次连接。此时,服务器会进入 CLOSED 状态,释放资源。

超时重传

TCP 为了实现可靠传输,实现了重传机制。最基本的重传机制,就是超时重传,即在发送数据报文时,设定一个定时器,每间隔一段时间,没有收到对方的ACK确认应答报文,就会重发该报文。

这个间隔时间,一般设置为多少呢?我们先来看下什么叫RTT(Round-Trip Time,往返时间)。

RTT就是,一个数据包从发出去到回来的时间,即数据包的一次往返时间。超时重传时间,就是Retransmission Timeout ,简称RTO。

RTO设置多久呢?

一般情况下,RTO略大于RTT,效果是最好的。一些小伙伴会问,超时时间有没有计算公式呢?有的!有个标准方法算RTO的公式,也叫Jacobson / Karels 算法。我们一起来看下计算RTO的公式

先计算SRTT(计算平滑的RTT)

SRTT = (1 - α) * SRTT + α * RTT  //求 SRTT 的加权平均

2. 再计算RTTVAR (round-trip time variation)

RTTVAR = (1 - β) * RTTVAR + β * (|RTT - SRTT|) //计算 SRTT 与真实值的差距

3. 最终的RTO

RTO = µ * SRTT + ∂ * RTTVAR  =  SRTT + 4·RTTVAR  

其中,α = 0.125,β = 0.25, μ = 1,∂ = 4,这些参数都是大量结果得出的最优参数。

4. 半连接队列和SYN Flood 攻击

在TCP的三次握手中,服务器发送SYN+ACK包之后,会等待客户端的ACK。如果ACK没有按时到达,可能是因为网络丢包或是恶意攻击(如SYN Flood攻击)

如果是网络不稳定,导致的网络丢包,一般我们重试都会成功的。还有个可能的原因,就是SYN Flood攻击。

SYN Flood是一种典型的DoS (Denial of Service,拒绝服务) 攻击,它在短时间内,伪造不存在的IP地址,向服务器大量发起SYN报文。当服务器回复SYN+ACK报文后,不会收到ACK回应报文,导致服务器上建立大量的半连接队列,半连接队列满了,这就无法处理正常的TCP请求啦。

5. TCP 三次握手的一些后端思想应用

TCP三次握手,背后蕴含的一些思想是可以应用到后端系统设计中的。

5.1 状态确认思想

比如,TCP三次握手确保双方都知道对方准备好进行通信,并且双方都能确认自己的消息被对方收到。这个机制本质上是一种状态同步和确认机制。

这种机制可以应用于分布式系统的节点间通信或客户端与服务端的连接建立。例如,在微服务之间的通信中,可以在建立连接前,进行双方的状态确认或健康检查,确保后续的通信是可靠的。

5.2 超时重试机制

再比如,TCP三次握手中,服务端会等待客户端的ACK确认包,如果没有收到,会根据一定策略进行重试,这背后是重试与超时的机制。

在后端服务中,重试机制和超时处理也非常重要。例如在调用第三方API时,如果网络波动导致请求失败,系统可以通过配置合理的重试策略(如指数退避、限流等)来提高成功率,同时避免过载。实例:HTTP请求的重试机制、消息队列的重发策略等。