当前位置: 首页 > news >正文

TCP 协议核心面试题 (附答案详解)

目录

Q1: 什么是 TCP 协议?它有哪些核心特点?

Q2: 请详细描述一下 TCP 的“三次握手”过程,并举例说明报文细节。

角色

三次握手真实报文流

① 第一次握手(SYN)

② 第二次握手(SYN+ACK)

③ 第三次握手(ACK)

连接建立后的第一个真实数据包

记忆口诀与核心目的

Q3: 为什么建立连接需要“三次握手”,而不是两次或四次?

Q4: 请详细描述一下 TCP 的“四次挥手”过程。

角色与初始状态

四次挥手真实报文流

① 第一次挥手(FIN)

② 第二次挥手(ACK)

③ 第三次挥手(FIN)

④ 第四次挥手(ACK)

状态变迁图(简化)

记忆口诀

Q5: 为什么断开连接需要“四次挥手”而不是三次?

Q6: TIME_WAIT 状态存在的意义是什么?

Q7: TCP 是如何保证可靠传输的?

Q8: 什么是 TCP “粘包”问题?该如何解决?

Q9: TCP 与 UDP 的区别是什么?


本文档旨在帮助准备技术面试的同学深入理解 TCP 协议的核心概念。内容涵盖了从基础的三次握手、四次挥手到深入的可靠性传输、流量控制和拥塞控制等常见面试考点。

在深入探讨具体的面试题之前,我们首先需要理解 TCP 报文头的核心组成部分,尤其是它的6个关键标志位 (Flags)。这些标志位就像是 TCP 通信中的“开关”或“信号灯”,控制着连接的建立、数据的传输和连接的终止。下面的表格言简意赅地总结了它们的核心作用:

标志位

何时置为 1

作用一句话

SYN

三次握手第 1、2 次

“我要同步序号,请求建立连接”

ACK

除第一个 SYN 包外的所有包

“确认号字段有效,我已收到你的数据”

FIN

四次挥手,主动关闭方发送

“我这边数据发完了,请求关闭连接”

RST

出现异常,需要强制断开连接

“连接出错了,立即复位,重新来过”

PSH

发送方希望数据立即被应用层接收

“别在缓冲区攒着了,立刻上交给应用程序”

URG

报文中存在紧急数据

“这里有紧急数据,需要优先处理”

理解了这些标志位,就掌握了分析所有 TCP 交互流程的关键。

Q1: 什么是 TCP 协议?它有哪些核心特点?

答: TCP (Transmission Control Protocol, 传输控制协议) 是一种工作在传输层的、面向连接的、可靠的基于字节流的通信协议。它是 TCP/IP 协议簇中的核心协议之一。

其核心特点包括:

  1. 面向连接 (Connection-Oriented): 在数据传输开始之前,通信双方必须先通过“三次握手”建立一个逻辑连接。数据传输结束后,需要通过“四次挥手”来断开连接。

  2. 可靠传输 (Reliable): TCP 提供了一套复杂的机制来确保数据能够完整、无误、按顺序地到达目的地。如果数据在传输中丢失、重复或损坏,TCP 能够检测到并进行重传。

  3. 全双工通信 (Full-Duplex): 一旦连接建立,通信双方可以同时进行数据的发送和接收。

  4. 基于字节流 (Byte Stream): TCP 将应用程序交付的数据看作是一个没有边界的、连续的字节序列。它不保留应用程序发送数据的记录边界,这可能导致“粘包”问题,需要应用层自己解决。

  5. 流量控制 (Flow Control): 通过滑动窗口机制,控制发送方的发送速率,防止因发送方速度过快而导致接收方缓冲区溢出。

  6. 拥塞控制 (Congestion Control): 当网络发生拥塞时,TCP 会降低发送速率,以减轻网络负荷,防止网络崩溃。

Q2: 请详细描述一下 TCP 的“三次握手”过程,并举例说明报文细节。

答: 当然,我们可以把三次握手当成“网购前先加微信确认身份”的场景,一步一步带入真实 TCP 报文数据,你就能看到序号、确认号、标志位是怎么跳动的。

角色
  • 客户端 C(你):想发送 20 字节的数据 HiServerHelloData...

  • 服务器 S(店家):正在监听 80 端口

  • 初始序号 (ISN) = 随机值(RFC 标准),这里为了方便理解,我们设定:

    • C 的 ISN = 1000

    • S 的 ISN = 2000

三次握手真实报文流
① 第一次握手(SYN)
  • C → S

  • 标志位SYN=1

  • 序号seq=1000

  • 负载:无数据

  • 含义:你好店家,我想建立连接,我的序号从 1000 开始。

② 第二次握手(SYN+ACK)
  • S → C

  • 标志位SYN=1, ACK=1

  • 序号seq=2000

  • 确认号ack=1001(即 1000+1,表示“你的序号 1000 我已收到,期待你的下一个序号 1001”)

  • 含义:好的,我收到了。我的序号从 2000 开始,并且我已经收到了你的 1000。

③ 第三次握手(ACK)
  • C → S

  • 标志位ACK=1

  • 序号seq=1001(正好是上一步服务器所期待的)

  • 确认号ack=2001(即 2000+1,表示“你的序号 2000 我也收到了”)

  • 负载:此时可以携带数据,也可以不带。这里假设先不带。

  • 含义:我也收到了你的 2000,连接建立完成!

连接建立后的第一个真实数据包
  • C → S

  • 标志位ACK=1(连接已建立,SYN 标志位置为 0)

  • 序号seq=1001

  • 确认号ack=2001

  • 负载:20 字节 "HiServerHelloData..."

  • 服务器收到后回应

    • ack=1021(即 1001 + 20),表示这 20 个字节的数据已全部收到。

记忆口诀与核心目的

SYN → SYN+ACK → ACK

三次握手完成后,双方各自都知道了对方的初始序号,这为后续数据的排序、去重和可靠重传打下了基础。连接正式建立,可以开始传输业务数据。

Q3: 为什么建立连接需要“三次握手”,而不是两次或四次?

答: 这是一个经典的面试题,主要考察对连接建立过程的深刻理解。

  • 为什么不能是两次握手? 主要原因是为了防止已失效的连接请求报文突然又传送到了服务器,从而产生错误

    • 场景: 客户端发送了一个连接请求 A,但由于网络延迟,这个请求没有立即到达服务器。客户端因为超时,又重新发送了一个连接请求 B。请求 B 正常到达并建立了连接,通信结束后释放了连接。

    • 问题: 如果此时那个延迟的请求 A 到达了服务器,服务器会误以为这是一个新的连接请求。如果是两次握手,服务器会立即发送确认并分配资源,然后等待客户端发送数据。但客户端实际上已经关闭,不会有任何响应。这会导致服务器单方面建立连接,白白浪费资源。

    • 三次握手如何解决: 有了第三次握手,即使服务器收到了失效的请求 A 并回复了确认,但由于客户端没有发出第三次握手(最终的 ACK),服务器就收不到确认,从而知道这是一个无效的连接,不会进入 ESTABLISHED 状态,也不会分配资源。

  • 为什么不需要四次握手? 三次握手已经足以验证双方的发送和接收能力,并同步了序列号。服务器在第二次握手中将 SYNACK 封装在一个报文中发送,没有必要拆分成两个独立的步骤。因此,四次握手是多余的,只会增加连接建立的时间。

Q4: 请详细描述一下 TCP 的“四次挥手”过程。

答: 我们可以把四次挥手想成“微信语音通话挂断”——双方都得说“我说完了,可以挂了”,否则可能漏话。下面用真实序号、标志位、状态机一步步演给你看。

角色与初始状态
  • 客户端 C:主动挂断方,刚发完数据,当前序号 = 1021

  • 服务器 S:被动挂断方,当前序号 = 2001

  • 双方连接状态 = ESTABLISHED

四次挥手真实报文流
① 第一次挥手(FIN)
  • C → S

  • 标志位FIN=1, ACK=1

  • 序号seq=1021

  • 确认号ack=2001

  • 负载:无数据

  • 状态:C 进入 FIN_WAIT_1

  • 含义:我话讲完了,要关闭发送方向了。

② 第二次挥手(ACK)
  • S → C

  • 标志位ACK=1

  • 序号seq=2001

  • 确认号ack=1022(1021+1,确认 FIN 占用一个序号)

  • 状态:S 进入 CLOSE_WAIT;C 收到后进入 FIN_WAIT_2

  • 含义:知道你要挂了,但我可能还有话要说,先别急。

③ 第三次挥手(FIN)
  • S → C

  • 标志位FIN=1, ACK=1

  • 序号seq=2001(假设中间无数据传输)

  • 确认号ack=1022

  • 状态:S 进入 LAST_ACK

  • 含义:我也说完了,现在可以关了。

④ 第四次挥手(ACK)
  • C → S

  • 标志位ACK=1

  • 序号seq=1022

  • 确认号ack=2002(2001+1,确认 FIN)

  • 状态:C 进入 TIME_WAIT;S 收到后进入 CLOSED

  • 含义:好的,双方都确认完成。2*MSL 后 C 也将彻底关闭。

状态变迁图(简化)
C: ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
S: ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED
记忆口诀

FIN — ACK — FIN — ACK

“我完”—“知道”—“我也完”—“好的”

Q5: 为什么断开连接需要“四次挥手”而不是三次?

答: 根本原因在于 TCP 是全双工的,连接的关闭需要双向进行

当客户端发送 FIN 请求关闭时,它仅仅表示客户端这一方不会再发送数据了。但此时服务器可能还有数据没有发送完毕。所以服务器不能立即也发送 FIN,而是先回复一个 ACK 告诉客户端:“你的关闭请求我收到了,但我可能还有话要说,请稍等”。

等到服务器将所有数据都发送完毕后,它才会发送自己的 FIN 报文,表示“我说完了,现在我这边也可以关闭了”。这就把第二次和第三次挥手分开了,导致总共需要四次挥手。

Q6: TIME_WAIT 状态存在的意义是什么?

答: TIME_WAIT 是主动关闭连接的一方在完成四次挥手后进入的状态。它会持续 2*MSL 的时间,主要有两个目的:

  1. 确保最后一个 ACK 报文能够可靠地到达服务器: 如果客户端发送的最后一个 ACK 报文在网络中丢失了,服务器会因为收不到确认而超时重传它的 FIN 报文。如果客户端没有 TIME_WAIT 状态而是直接关闭,那么它将无法响应服务器重传的 FIN,导致服务器无法正常关闭。TIME_WAIT 状态的存在,可以确保客户端有足够的时间来重发丢失的 ACK,帮助服务器正常关闭。

  2. 防止已失效的报文段影响新的连接: 假设一个 TCP 连接断开后,一个具有相同“四元组”(源 IP, 源端口, 目的 IP, 目的端口)的新连接被立即建立。如果没有 TIME_WAIT,网络中上一个连接延迟的、旧的报文段可能会被这个新连接误接收,造成数据混乱。等待 2*MSL 时间,可以确保上一个连接中所有在网络中滞留的报文段都已自然消失,从而不会干扰到新连接。

Q7: TCP 是如何保证可靠传输的?

答: TCP 通过多种机制协同工作来保证其可靠性:

  1. 序列号 (Sequence Number) 和确认应答 (Acknowledgment): TCP 将每个字节的数据都进行了编号,即序列号。接收方收到数据后,会发送一个 ACK 报文进行确认,ACK 报文中包含了期望收到的下一个字节的序列号。这样发送方就能知道哪些数据已经被对方成功接收。

  2. 校验和 (Checksum): 发送方和接收方都会对 TCP 报文段(头部和数据)进行校验和计算。如果接收方发现校验和有差错,就会丢弃该报文段,不发送 ACK,等待发送方超时重传。

  3. 超时重传 (Timeout Retransmission): 发送方在发送数据后会启动一个计时器。如果在计时器超时之前没有收到对该数据的确认,就认为数据丢失,并重新发送。

  4. 快速重传 (Fast Retransmission): 如果接收方收到了一个乱序的报文段,它会立即发送一个重复的 ACK,指明它期望的序列号。当发送方连续收到三个或以上重复的 ACK 时,它会意识到某个报文段可能已经丢失,于是在计时器超时之前就立即重传该报文段。

  5. 流量控制 (Flow Control): 使用滑动窗口机制,确保发送方不会发送超过接收方处理能力的数据量。

  6. 拥塞控制 (Congestion Control): 监测网络状况,动态调整发送速率,防止网络拥塞。

Q8: 什么是 TCP “粘包”问题?该如何解决?

答:

  • 问题描述: “粘包”问题并非 TCP 协议本身的问题,而是由于其字节流特性导致的。应用程序的多次 send 操作,在 TCP 层面可能会被合并成一个数据包发送(粘包);或者应用程序的一次 send 操作,数据量较大,在 TCP 层面可能会被拆分成多个数据包发送(拆包)。这导致接收方无法从字节流中区分出消息的边界。

  • 解决方案: 这个问题需要在应用层协议层面来解决。常见的方法有:

    1. 固定长度消息: 发送方将每条消息都封装成固定的长度,不足的部分用特殊字符填充。接收方每次都读取固定长度的数据作为一个完整的消息。

    2. 使用特殊分隔符: 在每条消息的末尾添加一个不会在消息正文中出现的分隔符(如 \r\n)。接收方通过扫描分隔符来切分消息。

    3. 消息头部+消息体: 在每条消息前附加一个固定长度的头部,头部中包含整个消息(或消息体)的长度。接收方先读取头部,解析出长度,然后再根据长度读取相应的数据作为一条完整的消息。这是最常用和最灵活的方法。

Q9: TCP 与 UDP 的区别是什么?

答:

特性

TCP (传输控制协议)

UDP (用户数据报协议)

连接性

面向连接

无连接

可靠性

可靠

不可靠,尽最大努力交付

传输模式

字节流

数据报

顺序

保证按序到达

不保证顺序

速度

较慢,开销大

较快,开销小

头部大小

较大,至少 20 字节

较小,固定 8 字节

控制机制

有流量控制和拥塞控制

应用场景

要求可靠性的应用:文件传输(HTTP, FTP)、邮件(SMTP)、远程登录(Telnet)

要求实时性的应用:视频会议、实时游戏、DNS、直播

http://www.dtcms.com/a/434382.html

相关文章:

  • Spring Security 实战:彻底解决 CORS 跨域凭据问题与 WebSocket 连接失败
  • Tabby下载安装与连接服务器
  • Apache Beam入门教程:统一批流处理模型
  • 计算机毕业设计 基于Hadoop的信贷风险评估的数据可视化分析与预测系统 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】
  • 【QT常用技术讲解】QTablewidget单元格存储隐藏的数据
  • K8s学习笔记(九) job与cronjob
  • MATLAB线性代数函数完全指南
  • 关于单片机外设存储芯片的应用笔记(IIC驱动)
  • 梅州网站建设南宁网站 制作
  • 2015 年真题配套词汇单词笔记(考研真相)
  • 中国建设银行舟山分行网站网站构建的过程
  • python如何通过链接下载保存视频
  • K-Lite Mega/FULL Codec Pack(视频解码器)
  • SpringBoot+Vue医院预约挂号系统 附带详细运行指导视频
  • 85-dify案例分享-不用等 OpenAI 邀请,Dify+Sora2工作流实测:写实动漫视频随手做,插件+教程全送
  • GUI高级工程师面试题
  • 经典网站设计风格网站建设产品介绍
  • 基于单片机的人体心率、体温监测系统(论文+源码)
  • WinScp下载与安装
  • 普中stm32大Dap烧录流程
  • 宝安附近做网站公司网站做好了前端 后端怎么做
  • 新媒体营销h5制作网站中国水土保持生态建设网站
  • ubuntu 服务器(带NVLink)更新显卡驱动 (巨坑!!)
  • jQuery提供了多种选择器,可以快速获取DOM元素
  • 【LaTeX】 6 LaTeX 扩展功能
  • 软件测试基础-03(缺陷)
  • 重庆建设公司网站做网站的工作好吗
  • GitHub 热榜项目 - 日榜(2025-10-02)
  • PEFT实战LoRA微调OpenAI Whisper 中文语音识别
  • Django第三方扩展详解:提升开发效率的利器