TCP协议为什么是三次握手而不是两次呢?

原因1:主要是为了防止已经失效的连接请求报文突然又传送到了服务器,从而导致不必要的错误和资源的浪费。

如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送的第一个请求连接并且没有丢失,只是因为在网络中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时之前滞留的那一次请求连接,因为网络通畅了, 到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

原因2: 两次握手只能保证单向连接是畅通的。因为TCP是一个双向传输协议,只有经过第三次握手,才能确保双向都可以接收到对方的发送的数据。

三次握手过程:

第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。

### TCP 三次握手的工作原理 TCP三次握手机制是为了建立可靠的通信连接而设计的一种协议机制。以下是其工作原理: 1. **第一次握手** 客户端向服务器发送一个 SYN(Synchronize Sequence Numbers)数据包,表示希望与服务器建立连接并同步序列号。此时,SYN 数据包中的 `seq` 字段会被设置为随机值 \(X\)【^1】。 2. **第二次握手** 服务器接收到客户端的 SYN 请求后,回复一个 SYN+ACK 数据包。其中,SYN 表示同意建立连接,ACK 是对客户端请求的确认。服务器会在 ACK 中携带客户端初始序列号加一 (\(X+1\)) 的值作为确认响应,同时也会提供自己的初始序列号 \(Y\)【^2】。 3. **第三次握手** 客户端再次发送一个 ACK 数据包给服务器,确认已经接收到来自服务器的 SYN 和 ACK 响应,并将服务器的初始序列号加一 (\(Y+1\)) 返回给服务器。至此,双方都完成了对方的初始化确认,从而建立了可靠的数据传输通道【^3】。 --- ### 使用三次握手的原因对比两次握手 如果仅使用两次握手,则可能会因为网络延迟或其他异常情况而导致旧有的、失效的连接请求重新到达目标主机,进而引发不必要的资源分配或安全风险。具体来说: - 如果只有两次握手,在某些情况下,当某个连接被中断之后,残留的连接请求可能仍然在网络中游荡。一旦这些过期的消息最终抵达目的地,就可能导致服务端误以为有新的合法连接需求,从而浪费计算资源或者暴露潜在漏洞【^2】。 - 而通过增加一次额外的手动验证环节——即第三步由客户端主动发起最后一步确认动作,可以有效避免上述问题的发生。这使得即使存在陈旧消息干扰的情况下,也能确保当前正在进行的是真实有效的交互过程【^3】。 因此,尽管相比起两阶段方法而言稍显复杂一些,但从稳定性和安全性角度来看,三阶段协商无疑更加优越合理。 ```python # Python模拟TCP三次握手逻辑示意代码 class TCPSession: def __init__(self, client_seq=0, server_seq=0): self.client_seq = client_seq self.server_seq = server_seq def start_handshake(self): # Client sends SYN to Server (First Handshake) syn_packet_client_to_server = {'type': 'SYN', 'seq': self.client_seq} # Server receives SYN and replies with SYN+ACK (Second Handshake) ack_value_for_client = syn_packet_client_to_server['seq'] + 1 new_server_seq = random.randint(1000,9999) # Simulate a random sequence number from the server side. syn_ack_packet_server_to_client = { 'type':'SYN_ACK', 'ack': ack_value_for_client, 'seq':new_server_seq } # Client acknowledges receipt of SYN+ACK by sending an ACK back (Third Handshake). final_ack_from_client={'type':'ACK','ack':syn_ack_packet_server_to_client['seq']+1} return f"Handshake completed successfully! Final Acknowledgement Value Sent Back To Server Is {final_ack_from_client['ack']}" session = TCPSession() print(session.start_handshake()) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值