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

架构师面试(二十二):TCP 协议

问题

今天我们聊一个非常常见的面试题目,不管前端还是后端,也不管做的是上层业务还是底层框架,更不管技术方向是运维还是架构,都可以思考和参与一下哈!

TCP协议无处不在,我们知道 TCP 是基于连接的端到端的且是有序和可靠的数据流式传输协议,可以记住这五个关键词哈:【基于连接】【端到端】【有序】【可靠】【流式传输】。 

今天的问题有两个:TCP协议是如何做到【可靠】数据传输的?既然 TCP 协议非常可靠,那为什么在应用层还需要 ACK 确认机制呢?(比如消息类软件:IM、MQ等)

解析

第一个问题考查的是计算机网络基础知识(我们在大厂高薪课讲过这个问题);

第二个问题考查的是网络知识在实际项目中的应用(我们在架构师课上也讲过这个问题哈)。

我们先来看第一个问题:“TCP 协议是如何做到【可靠】数据传输的?”

怎么理解这里的【可靠】呢?

节点 A  要把数据 “hello” 传输给节点 B,其结果就是 节点B一定会收到数据“hello”,这就是【可靠】。

针对这样的场景,【可靠】如何落地呢?

节点 A  需要知道节点 B 已经收到了数据,而且节点 B 收到的就是节点 A 发送的 “hello”,不是“hi”,也不是"HELLO"。

对【可靠数据传输的落地实践】总结两点:

一是 发送方收到了接收方接受数据的事件;

二是 接收方接受的数据就是发送方发送的数据。

这两点在 TCP 协议中是如何体现的?

第一点是通过【序列号和确认号机制】;

第二点是通过【校验和机制】。

先说【序列号和确认号机制】

在 TCP 协议头中,有一个 seq 字段(即序列号,32位长)和一个 ack 字段(即确认号,32位长)。

TCP 协议传输的字节流中,每一个字节都是有编号的,seq 字段就是要传输的一段字节流的第一个字节的编号;假设发送方要发送的报文的第一个字节编号是 100,而报文长度是 200,那么发送时 seq =100,下一次要发送报文时,seq=300。

而 确认号 ack 字段表示 接收方期望收到下一个报文的第一个字节的编号;还是刚才这个例子,发送方 seq=100,报文长度=200,接收方收到后在回复时,需要  ack=300;也就是编号 299 及之前的字节流我都收到了。

序列号 seq 和确认号 ack 不但完成了接收数据确认的任务,也完成了对有序数据的职责。

再说【校验和机制】

TCP 在传输数据时,发送方将数据段都当做一个 16 位的整数,将这些整数加起来(进位补在后面,不能丢弃),然后取反,得到校验和;接收方收到数据后,再进行相同的运算,得到校验和,与发送方的校验和进行比对,来判断 收到的 “hello” 是不是发送方发送的 “hello”。

通过以上【序列号和确认号机制】和【校验和机制】可以确认数据是可靠传输的,这毕竟是一次数据传输的可靠,那如何保证数据能持续性的可靠传输呢?有三个常用的策略和手段:

(1)超时重传:我们知道 TCP 协议不是每一次数据发送都有对应的 ack 包的,但是长时间没有ack 包就不应该了,此时可以通过 超时重传 机制来重发数据;

(2)流量控制:如果接收方应用层程序处理逻辑太慢,会导致 TCP 接收缓冲区被数据占满,此时再发送数据已然无意义,需要控制流量了;TCP 通过 滑动窗口解决这个问题;

(3)拥塞控制:【流量控制】表征的是接收方接收和处理数据的能力,如果数据在传输过程中出现了拥堵怎么办呢?这就需要拥塞控制了,TCP通过 拥塞窗口解决这个问题;值得一提的是, TCP是具有自我牺牲精神的,出现了交通拥堵,不会争着抢着去跑,一般都会主动让出道路。

我们再来看第二个问题:“既然 TCP 协议非常可靠,那为什么在应用层还需要 ACK 确认机制呢?”

TCP协议非常可靠,是指在连接没有断开的时候;

我们可以这样讲:如果在程序运行的整个生命周期中,TCP 连接处于理想环境中,没有任何外部因素导致它中断,那么应用层是可以不需要 ACK 确认机制的。

我们简单分析一下数据传输过程:

发送方基于 TCP 协议将数据发送到接收方的 TCP 缓冲区,TCP 缓冲区工作在 TCP 层,由操作系统控制;操作系统内核会将 TCP 缓冲区的数据拷贝到应用层,由工作在应用层的进程进行处理。

当 TCP 连接断开的时候,操作系统会一直保留 TCP 缓冲区中还未处理的数据吗?

肯定不会(一是为了释放内存,节省资源;二是连接断开后,会尽快重连的,此时必须为新的连接开辟一块干净的空间,不会对之前的 TCP 缓冲区进行复用的),操作系统会直接回收 TCP 缓冲区,也就意味着数据丢失了;因此在应用层进行 ACK 确认机制是必要的。

我们可以想象一下:我们在应用层尽情的接收着数据,这些数据很多时候来自 TCP 层不同时间段创建的多条TCP连接。

上面啰嗦了很多,是为了尽最大努力帮助大家理解;最后对问题进行简单总结:

TCP 协议是如何做到【可靠】数据传输的?通过【序列号和确认号机制】和【校验和机制】,辅助手段是 【超时重传】【滑动窗口】【拥塞窗口】;

既然 TCP 协议非常可靠,那为什么在应用层还需要 ACK 确认机制呢?TCP 传输数据是可靠的,但不能保证 TCP 缓冲区的数据一定能到应用层。

相关文章:

  • PDF处理控件Spire.PDF系列教程:使用 JavaScript 在 React 中将 PDF 转换为 HTML
  • java八股文之企业场景
  • rv1106抓h264流
  • 从泛读到精读:合合信息文档解析如何让大模型更懂复杂文档
  • 【leetcode刷题记录】(java)贪心
  • Netty - 从Nginx 四层(TCP/UDP)流量中获取客户端真实/网络出口IP
  • Java实现pdf中动态插入图片
  • 如何在 Postman 中正确设置 Session 以维持用户状态?
  • 亚马逊云科技提供完全托管的DeepSeek-R1模型
  • SEO(搜索引擎优化)详解
  • 处理脚本中函数调用的异常
  • 基于深度强化学习的智能机器人路径规划技术研究
  • 第六届 蓝桥杯 嵌入式 省赛
  • Postman CORS 测试完全指南:轻松模拟跨域请求,排查 CORS 相关问题
  • 软考中级-软件设计师 23种设计模式(内含详细解析)
  • Gateway实战(二)、负载均衡
  • React 中shouldComponentUpdate生命周期方法的作用,如何利用它优化组件性能?
  • Python爬虫如何检测请求频率?
  • Docker-Volume数据卷详讲
  • 循环神经网络 - 给网络增加记忆能力
  • 上海市税务局:收到对刘某某存在涉税问题的举报,正依法依规办理
  • 《上海市建筑信息模型技术应用指南(2025版)》发布
  • 当番茄霸总遇上晋江古言,短剧IP小变局
  • 7月纽约举办“上海日”,上海大剧院舞剧《白蛇》连演三场
  • 中央结算公司:减免境外央行类机构账户开户费用
  • 智能手表眼镜等存泄密隐患,国安部提醒:严禁在涉密场所使用