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

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时有效) 。

相关文章:

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

一、特点: (一)面向连接 在进行数据传输之前,TCP 需要在发送方和接收方之间建立一条逻辑连接。这一过程类似于打电话,双方在通话前需要先拨号建立连接。建立连接的过程通过三次握手来完成,确保通信双方都…...

【小白训练日记——2025/4/15】

变化检测常用的性能指标 变化检测(Change Detection)的性能评估依赖于多种指标,每种指标从不同角度衡量模型的准确性。以下是常用的性能指标及其含义: 1. 混淆矩阵(Confusion Matrix) 定义:统…...

交叉熵在机器学习中的应用解析

文章目录 核心概念香农信息量(自信息)熵(Entropy)KL散度(Kullback-Leibler Divergence)交叉熵 在机器学习中的应用作为损失函数对于二分类(Binary Classification):对于多…...

ARM Cortex汇编指令

在ARM架构的MCU开发中,汇编指令集是底层编程的核心。以下是针对Cortex-M系列(如M0/M3/M4/M7/M85)的指令集体系、分类及查询方法的详细说明: 一、指令集体系与核心差异 1. 架构版本与指令集特性 处理器架构指令集特点典型应用场…...

数据结构——二叉树(中)

接上一篇,上一篇主要讲解了关于二叉树的基本知识,也是为了接下来讲解关于堆结构和链式二叉树结构打基础,其实无论是堆结构还是链式二叉树结构,都是二叉树的存储结构,那么今天这一篇主要讲解关于堆结构的实现与应用 堆…...

InnoDB的MVCC实现原理?MVCC如何实现不同事务隔离级别?MVCC优缺点?

概念 InnoDB的MVCC(Multi-Version Concurrency Control)即多版本并发控制,是一种用于处理并发事务的机制。它通过保存数据在不同时间点的多个版本,让不同事务在同一时刻可以看到不同版本的数据,以此来减少锁竞争&…...

UDP目标IP不存在时的发送行为分析

当网络程序使用UDP协议发送数据时,如果目标IP不存在,发送程序的行为取决于网络环境和操作系统的处理机制。以下是详细分析: 1. UDP的无连接特性 UDP是无连接的传输协议,发送方不会预先建立连接,也不会收到对方是否存在…...

WHAT - 动态导入模块遇到版本更新解决方案

文章目录 一、动态导入模块二、常见原因与解决方案1. 模块 URL 错误2. 开发人员发版用户停留在旧页面问题背景解决方案思路1. 监听错误,提示用户刷新2. 使用缓存控制策略:强制刷新3. 动态模块加载失败时兜底4. 使用 import.meta.glob() 或 webpack 的 __…...

02-MySQL 面试题-mk

文章目录 1.mysql 有哪些存储引擎、区别是什么?1.如何定位慢查询?2.SQL语句执行很慢,如何分析?3.索引概念以及索引底层的数据结构4.什么是聚簇索引什么是非聚簇索引?5.知道什么叫覆盖索引嘛 ?6.索引创建原则有哪些?7.什么情况下索引会失效 ?8.谈一谈你对sql的优化的经验…...

#include<bits/stdc++.h>

#include<bits/stdc.h> 是 C 中一个特殊的头文件&#xff0c;其作用如下&#xff1a; 核心作用 ​​包含所有标准库头文件​​ 该头文件会自动引入 C 标准库中的几乎全部头文件&#xff08;如 <iostream>、<vector>、<algorithm> 等&#xff09;&…...

PostgreSQL:逻辑复制与物理复制

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程,高并发设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s,热衷于探…...

在企业级部署中如何优化NVIDIA GPU和容器环境配置:最佳实践与常见误区20250414

在企业级部署中如何优化NVIDIA GPU和容器环境配置&#xff1a;最佳实践与常见误区 引言 随着AI和深度学习技术的迅速发展&#xff0c;企业对GPU加速计算的需求愈加迫切。在此过程中&#xff0c;如何高效地配置宿主机与容器化环境&#xff0c;特别是利用NVIDIA GPU和相关工具&…...

iphone各个机型尺寸

以下是苹果&#xff08;Apple&#xff09;历代 iPhone 机型 的屏幕尺寸、分辨率及其他关键参数汇总&#xff08;截至 2023年10月&#xff0c;数据基于官方发布信息&#xff09;&#xff1a; 一、标准屏 iPhone&#xff08;非Pro系列&#xff09; 机型屏幕尺寸&#xff08;英寸…...

栈的学习笔记

使用数组实现一个栈 #include <stdio.h>#define MAX_SIZE 101int A[MAX_SIZE]; int top -1; //栈顶指针&#xff0c;初始为-1&#xff0c;表示栈为空 void push(int x) {if (top MAX_SIZE - 1){printf("栈已满&#xff0c;无法入栈\n");return;}A[top] x;…...

Spring Boot 项目三种打印日志的方法详解。Logger,log,logger 解读。

目录 一. 打印日志的常见三种方法&#xff1f; 1.1 手动创建 Logger 对象&#xff08;基于SLF4J API&#xff09; 1.2 使用 Lombok 插件的 Slf4j 注解 1.3 使用 Spring 的 Log 接口&#xff08;使用频率较低&#xff09; 二. 常见的 Logger&#xff0c;logger&#xff0c;…...

按键精灵安卓/ios脚本辅助工具开发教程:如何把界面配置保存到服务器

在使用按键精灵工具辅助的时候&#xff0c;多配置的情况下&#xff0c;如果保存现有的配置&#xff0c;并且读取&#xff0c;尤其是游戏中多种任务并行情况下&#xff0c;更是需要界面进行保存&#xff0c;简单分享来自紫猫插件的配置保存服务器写法。 界面例子&#xff1a; …...

[react]Next.js之自适应布局和高清屏幕适配解决方案

序言 阅读前首先了解即将要用到的两个包的作用 1.postcss-pxtorem 自动将 CSS 中的 px 单位转换为 rem 单位按照设计稿尺寸直接写 px 值&#xff0c;由插件自动计算 rem 值 2.amfe-flexible 动态设置根元素的 font-size&#xff08;即 1rem 的值&#xff09;根据设备屏幕宽度和…...

STM32H503CB升级BootLoader

首先&#xff0c;使用SWD接口&#xff0c;ST-LINK连接电脑和板子。 安装SetupSTM32CubeProgrammer_win64 版本2.19。 以下是接线和软件操作截图。...

在Apple Silicon上部署Spark-TTS:四大核心库的技术魔法解析!!!

在Apple Silicon上部署Spark-TTS&#xff1a;四大核心库的技术魔法解析 &#x1f680; &#xff08;M2芯片实测&#xff5c;Python 3.12.9PyTorch 2.6.0全流程解析&#xff09; 一、核心库功能全景图 &#x1f50d; 在Spark-TTS的部署过程中&#xff0c;pip install numpy li…...

VMWare 16 PRO 安装 Rocky8 并部署 MySQL8

VMWare 16 PRO 安装 Rocky8 并部署 MySQL8 一.Rocky OS 下载1.官网二.配置 Rocky1.创建新的虚拟机2.稍后安装系统3.选择系统模板4.设置名字和位置5.设置大小6.自定义硬件设置核心、运存和系统镜像7.完成三.启动安装1.上下键直接选择安装2.回车安装3.设置分区(默认即可)和 roo…...

cursor如何回退一键回退多个文件的修改

当我们使用 Cursor 写代码时&#xff0c;起初可能操作得很顺利&#xff0c;但某次更改或许会让代码变得面目全非。这时候如果没有使用 Git 该怎么办呢&#xff1f;别担心&#xff0c;Cursor 已经为我们考虑到了。 具体的操作如下&#xff1a; 当我们要取消某次操作时&#xf…...

基于RV1126开发板的口罩识别算法开发

1. 口罩识别简介 口罩识别是一种基于深度学习的判断人员有没有戴口罩的分类算法&#xff0c;能广泛的用于安防、生产安全等多种场景。本算法先基于人脸检测和人脸标准化获取的标准人脸&#xff0c;然后输入到口罩识别分类算法进行识别。 本人脸检测算法在数据集表现如下所示&am…...

PyCharm显示主菜单和工具栏

显示主菜单 新版 PyCharm 是不显示主菜单的&#xff0c;要想显示主菜单和工具栏&#xff0c;则通过 “视图” → “外观” &#xff0c;勾选 “在单独的工具栏中显示主菜单” 和 “工具栏” 即可。 设置工具栏 此时工具栏里并没有什么工具&#xff0c;因此我们需要自定义工具…...

Java工程行业管理软件源码 - 全面的项目管理工具 - 工程项目模块与功能一览

工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 项目背景 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管理的提升提…...

Redis 高可用集群搭建与优化实践

在分布式系统中,缓存技术用于提升性能和响应速度。 Redis 作为一款高性能的键值存储系统,广泛应用于缓存、消息队列和会话管理等场景。随着业务规模的扩大,单机 Redis 的性能和可用性逐渐无法满足需求。 因此,搭建高可用的 Redis 集群可以解决这一问题。我将详细介绍 Red…...

利用多GPU计算探索量子无序及AI拓展

量子无序系统的领域是凝聚态物理学中一个引人入胜的前沿。与它们完全有序的对应物不同&#xff0c;这些材料表现出量子力学和内在随机性的复杂相互作用&#xff0c;导致了许多令人着迷且常常难以理解的行为。量子自旋玻璃就是一个典型的例子&#xff0c;在这种系统中&#xff0…...

【AI大模型】基于阿里百炼大模型进行调用

目录 一、认识阿里云百炼 模型广场 创建自己的模型 二、AI扩图示例 1、开头服务、设置秘钥 2、选择HTTP方式调用流程 3、创建任务请求示例 4、发送http请求提交任务 5、查看任务进度的流程设计 6、后端查看任务进度代码 三、总结 大家好&#xff0c;我是jstart千语…...

【神经网络结构的组成】深入理解 转置卷积与转置卷积核

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;《深度学习理论直觉三十讲》_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 …...

数据战略新范式:从中台沉淀到服务觉醒,SQL2API 如何重塑数据价值链条?

一、数据中台退烧&#xff1a;从 “战略神话” 到 “现实拷问” 曾几何时&#xff0c;数据中台被视为企业数字化转型的 “万能解药”&#xff0c;承载着统一数据资产、打破业务壁垒的厚望。然而&#xff0c;大量实践暴露出其固有缺陷&#xff1a;某零售企业投入 500 万元建设中…...

Docker 代理配置全攻略:从入门到企业级实践

Docker 代理配置终极指南&#xff1a;从原理到实践 在企业环境中&#xff0c;Docker 的网络访问常常需要通过代理来完成&#xff0c;例如拉取镜像或在容器内访问外部网络。本文将从核心流程、配置方法到验证步骤&#xff0c;全面解析 Docker 代理的配置方式&#xff0c;助你轻…...