TCP 如何在网络 “江湖” 立威建交?

一、特点:

(一)面向连接

在进行数据传输之前,TCP 需要在发送方和接收方之间建立一条逻辑连接。这一过程类似于打电话,双方在通话前需要先拨号建立连接。建立连接的过程通过三次握手来完成,确保通信双方都做好了数据传输的准备。连接建立后,数据按照顺序有序传输,直到通信结束,通过四次挥手关闭连接。

(二)可靠性
  1. 校验和:TCP 在发送数据时,会对数据部分计算校验和,并将校验和放入 TCP 首部。接收方在接收到数据后,会重新计算校验和并与接收到的校验和进行对比。如果两者不一致,说明数据在传输过程中出现了错误,接收方会要求发送方重新发送数据。
  2. 确认机制:接收方收到数据后,会向发送方发送确认(ACK)消息,告知发送方数据已成功接收。发送方在发送数据后,会启动一个定时器,如果在定时器超时之前没有收到 ACK,就会认为数据传输失败,并重发数据。
  3. 重传机制:除了超时重传,TCP 还采用了快速重传机制。当接收方连续收到三个相同的 ACK 时,就会认为中间的数据段丢失,发送方会立即重传丢失的数据段,而不需要等待定时器超时,大大提高了数据传输的效率。
  4. 排序与重复数据处理:TCP 会对接收的数据按照序号进行排序,确保数据按顺序交付给应用层。同时,对于重复接收的数据,TCP 会进行丢弃处理,保证应用层不会接收到重复的数据。
(三)字节流服务

TCP 将数据视为无结构的字节流进行传输,应用层可以按照任意大小的数据块进行读写,而不必担心数据的边界问题。TCP 会在发送方将数据分割成合适大小的段进行传输,并在接收方将这些段重新组装成完整的字节流交付给应用层。

二、连接管理机制

(一)连接建立(三次握手)
  1. 第一次握手:客户端向服务器发送一个带有 SYN(同步序列号)标志位的 TCP 报文段,该报文段中包含客户端随机生成的初始序列号(Sequence Number,简称 SEQ),假设为 x。此时客户端进入 SYN_SENT 状态,等待服务器的响应。
  2. 第二次握手:服务器接收到客户端的 SYN 报文段后,向客户端发送一个 SYN + ACK 报文段。该报文段中的 SYN 标志位表示服务器同意建立连接,ACK 标志位用于确认收到客户端的 SYN。服务器也会生成一个自己的初始序列号,假设为 y,并将客户端的序列号 x 加 1 作为确认号(Acknowledgment Number,简称 ACK),即 ACK = x + 1。此时服务器进入 SYN_RCVD 状态。
  3. 第三次握手:客户端接收到服务器的 SYN + ACK 报文段后,向服务器发送一个 ACK 报文段。该报文段的 ACK 标志位有效,确认号为服务器的序列号 y 加 1,即 ACK = y + 1,序列号为客户端在第一次握手中发送的序列号 x 加 1,即 SEQ = x + 1。此时客户端和服务器都进入 ESTABLISHED 状态,连接建立成功。
(二)数据传输

连接建立后,客户端和服务器就可以进行数据传输了。发送方将应用层的数据分割成 TCP 段,每个 TCP 段包含 TCP 首部和数据部分。TCP 首部中包含源端口、目的端口、序列号、确认号、标志位等信息。发送方按照序列号顺序发送数据段,接收方接收数据段后,根据序列号进行排序,并向发送方发送 ACK 确认。如果发送方在规定时间内没有收到 ACK,就会重发数据段。

(三)连接关闭(四次挥手)
  1. 第一次挥手:客户端向服务器发送一个 FIN(结束标志位)标志位有效的 TCP 报文段,表示客户端不再发送数据,但仍可以接收数据。此时客户端进入 FIN_WAIT_1 状态。
  2. 第二次挥手:服务器接收到客户端的 FIN 报文段后,向客户端发送一个 ACK 报文段,确认收到客户端的 FIN,此时服务器进入 CLOSE_WAIT 状态。客户端收到 ACK 后,进入 FIN_WAIT_2 状态。
  3. 第三次挥手:服务器在处理完剩余的数据后,向客户端发送一个 FIN 标志位有效的 TCP 报文段,表示服务器也不再发送数据。此时服务器进入 LAST_ACK 状态。
  4. 第四次挥手:客户端接收到服务器的 FIN 报文段后,向服务器发送一个 ACK 报文段,确认收到服务器的 FIN。此时客户端进入 TIME_WAIT 状态,经过一段时间(通常为 2 倍的最大段生存期,即 2MSL)后,客户端进入 CLOSED 状态,彻底关闭连接。服务器在收到客户端的 ACK 后,立即进入 CLOSED 状态。

看到这,有的读友可能会想到,建立连接时为什么需要3次握手?请求+响应两次握手不行吗?接下来就一同看看两次握手会出现什么问题。

如上图左边场景,客户端选择一个初始序列号x,发送连接请求报文 req_conn(x)给服务器,服务器接收到连接请求后,发送确认连接报文acc_conn(x),并且进入已连接状态。而在客户端超时定时器到时的时候,客户端没有接收到服务器的确认报文。此时,客户端重发连接请求req_conn(x) ,一会儿,第一次的acc_conn到达客户端处,连接建立,进行数据通信,然后通信结束。结束后,重发的req_conn(x)到达了服务器,服务器端会认为又建立了一个新连接(因为它不记得之前已经处理过 ),又会发送acc_conn(x),而客户端会忽略这个确认(因为已经建立连接 )。这就导致服务器端维护了多余的、不完整的连接(半连接 )。服务器端资源被无效占用,连接管理也出现混乱。

由此可看出,2次握手导致半连接问题

再看右侧场景,建立连接过程中,由于某种原因,服务器端ack迟迟不到,致使客户端超时重发req_conn(x),此后,延迟的ack到达客户端,连接建立。客户端向服务器发送数据,而又由于某种原因,dataack迟迟不到,客户端超时重发数据data.重发后延迟的ack到达客户端,通信结束,连接关闭。此后,重发的req_conndata到达服务器,使得老的数据被当作新的数据接收。这将导致数据错乱,业务逻辑错误

综上,二次握手存在的问题如下:

问题类型

根本原因

后果

三次握手解决方案

半连接

缺乏客户端最终确认

服务器资源浪费,通信中断

通过第三次ACK验证连接有效性

旧数据误认

无法区分历史连接与新连接

数据错乱,业务逻辑错误

动态ISN + 序列号严格同步

双向能力未验证

仅验证单向可达性

单向通信风险(如服务器→客户端不可达)

三次交互确认双向链路

因此,必须采用三次握手。

三、可靠数据传输

1. 确认应答(ACK)机制
  • 序列号与确认号:每个数据包携带32位序列号(SEQ)标识字节流起始位置,接收方通过确认号(ACK=SEQ+数据长度)反馈已接收的数据范围。例如,发送方发送SEQ=1000、长度500的数据,接收方返回ACK=1500
  • ACK标志位:TCP头部中ACK标志位为1时,表示该报文为确认报文,此时确认号字段生效。普通数据报文ACK标志位为0 。
  • 累积确认:接收方仅需确认连续接收的最高序列号,简化ACK处理。例如,若接收方已收到SEQ=1000-2000的数据,即使中间有乱序包(如SEQ=2500),仍返回ACK=2001,触发发送方选择性重传 。
2. 超时重传与动态RTO
  • 重传触发条件:发送方在动态计算的重传超时时间(RTO)内未收到ACK,触发数据包重传。RTO基于往返时间(RTT)自适应调整,计算公式为:
SRTT = (1-α) * SRTT + α * RTT_sample  
DevRTT = (1-β) * DevRTT + β * |RTT_sample - SRTT|  
RTO = SRTT + 4 * DevRTT

其中,α=0.125,β=0.25(经验值)。

  • 超时加倍策略:首次超时后,RTO逐次加倍,避免网络拥塞恶化 。
  • 接收缓冲区去重:接收方通过缓冲区存储已接收数据并按序重组,丢弃重复数据包(如因重传导致的冗余包) 。
3. 滑动窗口与高效传输
  • 窗口动态调整:发送窗口大小(SWND)取接收窗口(RWND)与拥塞窗口(CWND)的最小值,确保发送速率匹配接收方处理能力和网络状态。
  • 批量发送与累积ACK:发送方可在窗口内连续发送多个数据包,接收方通过累积ACK减少确认次数。例如,发送窗口为4时,发送SEQ=1-4的数据包,接收方返回ACK=5确认全部接收。
  • 选择性确认(SACK):通过TCP选项字段标记非连续接收的数据块范围,发送方仅重传丢失的包(如接收方反馈SACK=3000-3500,发送方重传缺失的2500-3000) 。
  • D-SACK:接收方通过SACK反馈重复接收的数据块,帮助发送方区分ACK丢失或网络延迟,优化重传策略 。
4. 拥塞控制
1. 慢开始(Slow Start):在连接建立初期,发送方将拥塞窗口(Congestion Window,简称 cwnd)初始化为一个最大段大小(MSS),然后每收到一个 ACK,就将拥塞窗口增加一个 MSS。这样,拥塞窗口呈指数增长,快速探测网络的承载能力。
2. 拥塞避免(Congestion Avoidance):当拥塞窗口增长到慢开始门限(ssthresh)时,进入拥塞避免阶段。在这个阶段,发送方每收到一个 ACK,就将拥塞窗口增加 1/cwnd 个 MSS,使拥塞窗口线性增长,避免网络拥塞。
3. 快重传(Fast Retransmit):当接收方连续收到三个相同的 ACK 时,发送方会立即重传丢失的数据段,而不需要等待定时器超时。这可以快速恢复丢失的数据,减少数据传输的延迟。
4. 快恢复(Fast Recovery):在快重传之后,发送方将慢开始门限设置为当前拥塞窗口的一半,然后将拥塞窗口设置为慢开始门限加上三个重复 ACK 所确认的数据量,接着进入拥塞避免阶段,而不是重新进入慢开始阶段。这样可以更快地恢复数据传输,提高网络的利用率。

四、流量控制

1. 滑动窗口工作机制
  • 接收窗口(RWND):接收方通过ACK报文中的窗口字段告知剩余缓冲区大小。例如,RWND=8000表示当前可接收8000字节数据 27。
  • 零窗口探测:若接收方缓冲区满(RWND=0),发送方启动持续计时器,定期发送1字节探测包,检测窗口恢复状态 27。
  • 窗口缩放选项:通过TCP选项扩展窗口字段位数(从16位至30位),支持高带宽网络的大窗口传输。
2. 流量控制的关键问题与解决
  • 糊涂窗口综合征(SWS)
    • 发送端SWS:Nagle算法解决小数据包问题,规则如下:
if 有新数据待发送:  if 窗口大小 ≥ MSS 且 数据量 ≥ MSS:  立即发送  elif 有未确认数据:  缓存数据等待ACK  else:  立即发送

此算法在高延迟场景可能导致小数据等待,可通过TCP_NODELAY选项 禁用

    • 接收端SWS:接收方在缓冲区不足时直接通告RWND=0,强制发送方暂停,待缓冲区清空后通过探测包恢复 。
3. 拥塞控制与流量控制的协同
  • 拥塞窗口(CWND):根据网络拥塞状态动态调整,通过慢启动(指数增长)和拥塞避免(线性增长)平衡带宽利用率 。
  • 全局平衡:最终发送速率受SWND = min(RWND, CWND)限制,同时避免接收方溢出和网络拥塞。

五、TCP报文格式

头部结构(20~60字节)

字段

长度

说明

源端口/目的端口

16位

标识应用程序(如HTTP=80)

序列号(SEQ)

32位

数据包首字节的全局位置

确认号(ACK)

32位

期望接收的下一个字节序号(仅当ACK=1时有效)

数据偏移

4位

首部长度(以4字节为单位,最大60字节)

控制标志

9位

SYN(连接请求)、ACK(确认)、FIN(终止)、RST(重置)、PSH(急迫推送)

窗口大小

16位

接收方可用缓冲区大小(流量控制关键参数)

校验和

16位

验证数据完整性

紧急指针

16位

标识紧急数据位置(仅当URG=1时有效) 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/78853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文章记单词 | 第29篇(六级)

一,单词释义 AI /ˌeɪ ˈaɪ/ abbr. 人工智能(Artificial Intelligence)inventory /ˈɪnvəntri/ n. 存货清单;财产清单;库存货物;存货;v. 编制目录;开列清单;盘存cha…

【C#】.NET 8适配器模式实战:用C#实现高可用系统集成与接口桥接艺术

系统集成挑战与适配器模式的价值 当需要整合不同架构或API的系统时,接口兼容性问题往往成为拦路虎。**适配器设计模式(Adapter Pattern)**通过转换接口形态,完美解决这种不兼容性问题。本文将通过C# .NET 8实战演示适配器模式的基…

Nginx基础到全面掌握高性能Web服务核心

目录 前言 第一部分:Nginx基础入门 1.1 什么是Nginx? 1.2 Nginx的典型应用场景 第二部分:Nginx安装与部署 2.1 在不同操作系统上安装Nginx 2.2 验证安装与基本操作 第三部分:Nginx配置详解 3.1 核心配置文件解析 3.2 虚…

C语言中while的相关题目

一、题目引入 以下程序中,while循环的循环次数是多少次? 二、代码分析 首先要明确的一点 while循环是当循环条件为真 就会一直循环 不会停止 while中i是小于10的 说明i可以取到0 1 2 3 4 5 6 7 8 9 进入第一个if判断i小于1为真时执行continue i0是为真的 执行continue 后…

idea 创建 maven-scala项目

文章目录 idea 创建 maven-scala项目1、创建普通maven项目并且配置pom.xml文件2、修改项目结构1)创建scala目录并标记成【源目录】2)导入scala环境3)测试环境 idea 创建 maven-scala项目 1、创建普通maven项目并且配置pom.xml文件 maven依赖…

微服务之间调用外键“翻译”的方法概述

写在前面的话&#xff1a;减少strean流操作&#xff0c;减少多层嵌套for循环。使用普通for循环和map的方式进行转换&#xff0c; 第一步查询数据 List<Student> findList studentDao.findList(findMap); 第二步准备遍历和赋值 if(CollectionUtil.isNotEmpty(findLis…

Spring Boot 中集成 Disruptor_高性能事件处理框架

1. 引言 1.1 什么是 Disruptor Disruptor 是一个高性能的事件处理框架,广泛应用于金融交易系统、日志记录、消息队列等领域。它通过无锁机制和环形缓冲区(Ring Buffer)实现高效的事件处理,具有极低的延迟和高吞吐量的特点。 1.2 为什么使用 Disruptor 高性能:通过无锁机…

Java中equals与 “==” 的区别

首先我们要掌握基本数据类型和引用类型的概念 基本数据类型&#xff1a; byte&#xff0c;short&#xff0c;int,long,float,double,boolean,char 基本的八大数据类型都各自封装着包装类&#xff0c;提供了更多的方法&#xff0c;并且都是引言类型 引用类型&#xff1a; 引…

青少年编程与数学 02-016 Python数据结构与算法 11课题、分治

青少年编程与数学 02-016 Python数据结构与算法 11课题、分治 一、分治算法的基本原理二、分治算法的实现步骤快速排序算法代码示例&#xff08;Python&#xff09; 三、分治算法的复杂度分析四、分治算法的优缺点优点&#xff1a;缺点&#xff1a; 五、分治算法的应用&#xf…

RFID技术概览

一、RFID技术定义 RFID&#xff08;Radio Frequency Identification&#xff0c;射频识别&#xff09; 是一种通过无线电信号识别目标对象并获取相关数据的非接触式自动识别技术。它利用射频信号的空间耦合&#xff08;电感或电磁耦合&#xff09;实现无物理接触的信息传递与目…

【C++游戏引擎开发】第13篇:光照模型与Phong基础实现

一、Phong模型数学原理 1.1 光照叠加公式 L = k a I a + k d I d max ⁡ ( 0 , n ⋅ l ) + k s I s max ⁡ ( 0 , r ⋅ v ) α L = k_a I_a + k_d I_d \max(0, \mathbf{n} \cdot \mathbf{l}) + k_s I_s \max(0, \mathbf{r} \cdot \mathbf{v})^\alpha L=ka​Ia​+kd​Id​max(0…

C语言中数组与指针:差异、应用及深度剖析

在C语言编程领域中&#xff0c;数组和指针是极为重要的概念&#xff0c;它们各自扮演着独特的角色&#xff0c;既有着紧密的联系&#xff0c;又存在显著的区别。深入理解它们的作用与差异&#xff0c;是掌握C语言编程的关键。 数组&#xff1a;数据的有序集合 数组是一组具有相…

【AI大模型】大模型RAG技术Langchain4j 核心组件深入详解

目录 一、前言 二、Langchain4j概述 2.1 Langchain4j 是什么 2.2 Langchain4j 主要特点 2.3 Langchain4j 核心组件 2.4 Langchain4j 核心优势 三、Langchanin4j组件应用实战 3.1 前置准备 3.1.1 导入如下依赖 3.1.2 获取apikey 3.1.3 获取官方文档 3.2 聊天组件 3.…

Web渗透之文件包含漏洞

文件包含漏洞原理 1、源代码 <?php$filename $_GET[filename]; include $filename; //或include_once,require,require_onceecho "欢迎来到PHP的世界.";?> 2、利用条件 php.ini中alllow_url_fopenOn(默认开启)和allow_url_includeOff(默认关闭)要开启…

MySQL 中查询 VARCHAR 类型 JSON 数据的

在数据库设计中&#xff0c;有时我们会将 JSON 数据存储在 VARCHAR 或 TEXT 类型字段中。这种方式虽然灵活&#xff0c;但在查询时需要特别注意。本文将详细介绍如何在 MySQL 中有效查询存储为 VARCHAR 类型的 JSON 数据。 一、问题背景 当 JSON 数据存储在 VARCHAR 列中时&a…

路由器开启QOS和UPNP的作用

QOS 的作用 保障关键业务带宽&#xff1a;可根据网络应用的重要性分配带宽。比如在家庭网络中&#xff0c;当多人同时使用网络时&#xff0c;将视频会议等实时性要求高的关键业务设置为高优先级&#xff0c;确保其能获得足够带宽&#xff0c;避免卡顿&#xff0c;而文件下载等…

5G网络下客户端数据业务掉线频繁

MCPTT&#xff08;Mission Critical Push-to-Talk&#xff09;客户端的日志&#xff0c;和界面在待机状态下&#xff08;即没有做通话等业务操作&#xff09;&#xff0c;会频繁提示“离线”。 主要先看有没有丢网&#xff0c;UL BLER有没有问题。确认没有问题。看到业务信道释…

使用Python和Matplotlib可视化字体轮廓:从路径数据到矢量图形

引言 字体设计和矢量图形处理是编程中一个有趣且实用的领域。通过Python的matplotlib库&#xff0c;我们可以轻松将字体轮廓的路径数据转换为直观的矢量图形。本文将带你一步步实现这一过程&#xff0c;并解析代码细节&#xff0c;帮助你理解如何将复杂的路径指令转化为可视化…

4.13日总结

javafx中实现发送qq邮箱验证码: 手动导入jar包方法&#xff1a; 第一步&#xff1a;开启QQ邮箱的 POP3/IMAP 或者 SMTP/IMAP 服务 打开qq邮箱&#xff08;电脑端&#xff09;&#xff0c;找到设置里的账号与安全的安全设置&#xff0c;往下滑就可以找到 POP3/IMAP 或者 SMTP…

智慧乡村数字化农业全产业链服务平台建设方案PPT(99页)

1. 农业全产业链概念 农业全产业链是依托数字化、电子商务、云计算等技术&#xff0c;整合规划咨询、应用软件设计与开发等服务&#xff0c;推动农业产业升级和价值重塑&#xff0c;构建IT产业融合新生态。 2. 产业链技术支撑 利用云计算、大数据、区块链等技术&#xff0c;为…