首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >字节跳动面试题:三次握手,为什么要三次而不是两次四次?

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

作者头像
GeekLiHua
发布2025-01-21 13:55:03
发布2025-01-21 13:55:03
4230
举报
文章被收录于专栏:JavaJava

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

三次握手的概念

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

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

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

为什么是三次握手?

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

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

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

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

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

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

代码语言:javascript
复制
# 客户端代码
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()
代码语言:javascript
复制
# 服务器端代码
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连接的状态转换图描述了连接的生命周期,包括连接的建立、数据传输和连接的终止。在三次握手的背景下,我将关注连接的建立阶段。

代码语言:javascript
复制
                +---------+                  +---------+
      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状态,连接关闭。
为什么不是两次握手或四次握手?

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-02-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 字节跳动面试题:三次握手,为什么要三次而不是两次四次?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档