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

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

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


三次握手的概念


三次握手是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状态,连接关闭。


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


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


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
6天前
|
网络协议 安全 Java
面试题:四次挥手
字节面试题:四次挥手
26 0
|
6天前
|
网络协议
跟着动画学习TCP三次握手和四次挥手,及全部面试题
跟着动画学习TCP三次握手和四次挥手,及全部面试题
43 0
|
6天前
|
网络协议 Java 数据库
面试回答TCP四次挥手问题及相关问题
面试回答TCP四次挥手问题及相关问题
37 0
|
6月前
|
网络协议
八股文-TCP的四次挥手
TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输协议,它的连接的建立和关闭过程都是经过精心设计的。在TCP连接关闭时,使用四次挥手来保证数据的完整传输和连接的正常终止。
66 3
八股文-TCP的四次挥手
|
6月前
|
网络协议
八股文-TCP的三次握手
TCP协议是一种面向连接、可靠传输的协议,而建立连接的过程就是著名的三次握手。这个过程保证了通信的双方能够同步信息,确保后续的数据传输是可靠和有序的。本文将深入解析TCP三次握手的步骤及其意义。
51 1
|
7月前
|
网络协议
TCP的三次握手,四次挥手,面试必会
TCP的三次握手,四次挥手,面试必会
|
7月前
|
网络协议 安全 Linux
TCP 三次握手与四次挥手深入探究(大图解)
TCP 三次握手与四次挥手深入探究(大图解)
198 1
|
8月前
|
网络协议
十人面试就我通过,只因我答对了这题TCP协议为什么需要三次握手
一位5年工作经验的小伙伴面试被问到这样一道面试题,说,TCP协议为什么要设计三次握手。当时这位小伙伴被问得哑口无言。后来,他找到我,说希望做一期视频分享一下。今天,我给大家分享一下我的理解。
37 0
|
缓存 网络协议 安全
【图解】三次握手,四次挥手 —— 用心看这一篇就够了
【图解】三次握手,四次挥手 —— 用心看这一篇就够了
2081 0
【图解】三次握手,四次挥手 —— 用心看这一篇就够了
|
前端开发
前端学习案例2-三次握手和四次挥手2
前端学习案例2-三次握手和四次挥手2
62 0
前端学习案例2-三次握手和四次挥手2