面试题:三次握手,为什么要三次而不是两次四次?

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 字节跳动面试题:三次握手,为什么要三次而不是两次四次?

面试题:三次握手,为什么要三次而不是两次四次?


三次握手的概念


三次握手是TCP协议用于建立连接的一种机制。它涉及到客户端和服务器之间的三个步骤,确保双方都能够正常通信。


  • 第一次握手(SYN): 客户端向服务器发送一个SYN(同步)标志,表示客户端希望建立连接。
  • 第二次握手(SYN + ACK): 服务器接收到客户端的SYN后,回应一个带有SYN和ACK(确认)标志的报文,表示服务器已准备好接受连接请求。
  • 第三次握手(ACK): 客户端接收到服务器的响应后,发送一个带有ACK标志的报文,表示客户端也已准备好建立连接。


这样,通过三次握手,双方确认彼此都能够正常通信,建立了可靠的连接。


为什么是三次握手?


为什么不是两次握手或四次握手呢?这涉及到建立连接的可靠性和防止网络中的不确定性。让我通过一个实际的案例来理解为什么三次握手是必要的。


案例分析:网络延迟引发的问题


假设我只有两次握手,而不是三次。客户端发送SYN,服务器回应SYN + ACK,看起来连接已经建立。但在这之后,由于网络延迟或其他原因,客户端并没有收到服务器的确认,导致客户端以为连接已建立,而服务器并不知情。


这种情况下,客户端和服务器之间的连接状态将变得不一致,可能导致各种问题,如资源浪费、连接超时等。为了防止这种情况,引入第三次握手可以确保双方都能够确认连接已经建立,避免了不确定性带来的问题。


代码示例:Python中的三次握手


让我通过一个简单的Python代码示例来演示三次握手的过程。

# 客户端代码
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('server_ip', 8080))

# 第一次握手
client.send(b'SYN')

# 第二次握手
response = client.recv(1024)
if b'SYN-ACK' in response:
    client.send(b'ACK')
    print('Connection established successfully!')
else:
    print('Connection failed.')

client.close()
# 服务器端代码
import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('server_ip', 8080))
server.listen(1)

client, addr = server.accept()

# 第一次握手
request = client.recv(1024)
if b'SYN' in request:
    client.send(b'SYN-ACK')

# 第三次握手
response = client.recv(1024)
if b'ACK' in response:
    print('Connection established successfully!')
else:
    print('Connection failed.')

client.close()
server.close()

安全性考虑


三次握手在一定程度上提高了连接的安全性。通过要求客户端和服务器都发送和确认连接请求,它减少了未经授权的连接建立的可能性。如果只有两次握手,可能会容易受到一些网络攻击,例如SYN洪泛攻击,因为服务器无法确认客户端是否真的要建立连接。


可靠性和状态同步


三次握手的每一步都具有明确定义的状态。第一次握手表示客户端希望建立连接,第二次握手表示服务器接受连接,并准备好接收数据,第三次握手表示客户端也确认连接建立。这种状态同步确保了双方都了解连接的当前状态。


处理网络延迟


三次握手的过程中,如果某一步的消息由于网络延迟未能及时到达,发送方会在一段时间后重新发送。这种机制有助于处理因为网络延迟引起的消息丢失,确保了连接的可靠性。


为什么不是两次握手?


如果只有两次握手,存在一些潜在的问题。例如,在两次握手中,服务器接收到连接请求后立即回应,这时连接就建立了。但如果这个回应由于网络延迟而在一段时间后才到达,客户端就无法得知连接是否真的建立成功。这可能导致客户端错误地认为连接已经建立,而服务器并不知情。


为什么不是四次握手?


四次握手是在连接关闭时使用的,与连接建立时的三次握手不同。在连接关闭时,需要双方确认彼此都已准备好断开连接。而在连接建立时,通过三次握手就能够确保连接的可靠性和安全性。


TCP连接的状态转换图


TCP连接的状态转换图描述了连接的生命周期,包括连接的建立、数据传输和连接的终止。在三次握手的背景下,我将关注连接的建立阶段。

                +---------+                  +---------+
      CLOSED    |  LISTEN |----------------->|  CLOSED |
                +---------+        Passive   +---------+
                  |     ^                   CLOSE
           OPEN   |     |                   /
                  v     |        +--------+
                +---------+     +->|  IDLE  |
                |  SYN-   |     |  / +-----+
                |  SENT   |<----+
                +---------+       |
                  |              |
                  |     Active   |
                  |              |
                  v              |
                +---------+       |
 +----------------|  SYN-   |       |
 |   Passive     |  RECEIVED |<------+
 |    OPEN       +---------+
 v      |              |
        |     Close    |
        |              |
 +------|              v
 |      |    +---------+
 |      +--->|  FIN-   |
 +------------>| WAIT-   |
        |     | CLOSE   |
        v     +---------+
      +-------------+
      |  CLOSED     |
      +-------------+

详细步骤:建立连接


让我通过更详细的步骤来理解三次握手的建立连接过程。


  1. 客户端向服务器发送SYN: 客户端初始处于CLOSED状态,向服务器发送一个SYN标志的TCP报文,进入SYN-SENT状态。
  2. 服务器接收SYN并回应SYN+ACK: 服务器接收到客户端的SYN后,回应一个带有SYN和ACK标志的报文,表示服务器已准备好接受连接。服务器进入SYN-RECEIVED状态。
  3. 客户端发送ACK: 客户端接收到服务器的响应后,发送一个带有ACK标志的报文,表示客户端也确认连接建立。客户端和服务器都进入ESTABLISHED状态,连接建立成功。


详细步骤:关闭连接


当连接建立后,双方通信完成后可能需要关闭连接。下面是关闭连接的详细步骤:


  1. 主动关闭方发送FIN: 主动关闭方(可以是客户端或服务器)发送一个带有FIN标志的TCP报文,表示它已经完成了数据的发送。
  2. 被动关闭方接收FIN并回应ACK: 被动关闭方接收到FIN后,回应一个带有ACK标志的报文,表示接收到了关闭请求。此时,被动关闭方进入CLOSE-WAIT状态。
  3. 主动关闭方接收ACK: 主动关闭方接收到ACK后,进入FIN-WAIT-1状态。
  4. 被动关闭方发送FIN: 被动关闭方也可能在完成数据的发送后发送FIN,进入LAST-ACK状态。
  5. 主动关闭方回应ACK: 主动关闭方接收到被动关闭方的FIN后,回应一个ACK,进入TIME-WAIT状态。
  6. 连接关闭: 在一定时间后,主动关闭方进入CLOSED状态,连接关闭。


为什么不是两次握手或四次握手?


两次握手存在的问题已经在前面的部分讨论过,容易导致不确定性。而四次握手是在连接关闭时使用的,与连接建立时的三次握手不同。三次握手在确保连接的可靠性、安全性和性能优化方面已经被广泛接受。


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
3月前
|
网络协议
通俗易懂理解三次握手、四次挥手(TCP)
这篇文章用通俗的语言解释了TCP协议中的三次握手和四次挥手过程,通过比喻和详细的状态变化描述,帮助读者理解建立和断开连接的原理和原因。
通俗易懂理解三次握手、四次挥手(TCP)
|
6月前
|
网络协议 安全 Java
面试题:四次挥手
字节面试题:四次挥手
53 0
|
6月前
|
网络协议 Java
【JavaEE初阶】 TCP三次握手四次挥手(超详细版)
【JavaEE初阶】 TCP三次握手四次挥手(超详细版)
|
6月前
|
网络协议
跟着动画学习TCP三次握手和四次挥手,及全部面试题
跟着动画学习TCP三次握手和四次挥手,及全部面试题
94 0
|
网络协议
八股文-TCP的四次挥手
TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输协议,它的连接的建立和关闭过程都是经过精心设计的。在TCP连接关闭时,使用四次挥手来保证数据的完整传输和连接的正常终止。
102 3
八股文-TCP的四次挥手
|
6月前
|
网络协议 Java 数据库
面试回答TCP四次挥手问题及相关问题
面试回答TCP四次挥手问题及相关问题
71 0
|
网络协议
八股文-TCP的三次握手
TCP协议是一种面向连接、可靠传输的协议,而建立连接的过程就是著名的三次握手。这个过程保证了通信的双方能够同步信息,确保后续的数据传输是可靠和有序的。本文将深入解析TCP三次握手的步骤及其意义。
84 1
|
网络协议 安全 Linux
TCP 三次握手与四次挥手深入探究(大图解)
TCP 三次握手与四次挥手深入探究(大图解)
552 1
|
网络协议
TCP的三次握手,四次挥手,面试必会
TCP的三次握手,四次挥手,面试必会
|
缓存 网络协议 安全
【图解】三次握手,四次挥手 —— 用心看这一篇就够了
【图解】三次握手,四次挥手 —— 用心看这一篇就够了
2613 0
【图解】三次握手,四次挥手 —— 用心看这一篇就够了