TCP 通信全流程分析:从连接建立到数据传输的深度探索
目录
一、TCP报头
二、三次握手
三、数据传输
四、四次挥手
本文通过一次TCP通信过程的分析来学习TCP协议
一、TCP报头
如图是一份TCP报文的报头,标准报头是20个字节,还可带有选项报头,也就是TCP报头的最小长度是20字节。以下是对报头的各个字段的分析:
- 端口号:向上层交付时交付给哪一个进程。
- 序列号:为发送的报文的编号,实际上是发送缓冲区的字节序号,旨在让接收方收到多个报文时可以通过序列号排序后向上层交付,还可以在收到重复报文时根据序列号去重。
- 确认序号:对发送端报文的应答,若确认序号为N,则表明N-1为止所有数据均已到达。
- 4位首部长度:表明报文的报头长度,单位是4字节;因为只有4位->最大值为15,意味着选项部分报头最大为40字节。
- 六个标记位:用于区分不同报文的类型,不同类型报文对应了不同的处理逻辑,所以需要用标记为进行区分。以下是具体解释:
- URG:紧急数据标记位,当URG被置为1时,报头的另一个字段:16位紧急指针中会指向对应的紧急数据,十六位紧急指针是有效载荷的偏移量,紧急数据只有一个字节。
- ACK:表明对以往收到的报文的确认,一般除了第一个请求报文没有设置ACK以外,其余报文基本都会设置ACK,因为发送出去的数据本身就对对方以往发送的报文具有一定的确认能力,因此双方在进行数据通信时,可以顺便对对方上一次发送的数据进行响应。
- PSH:报文当中的PSH被设置为1,是在告诉对方尽快将接收缓冲区当中的数据交付给上层。因为内核中的接收缓冲区都会有一个水位线,正常情况下只有数据大小超过了水位线才会允许上层读取数据,以减少内核态和用户态来回切换的成本;但当收到的报文带有PSH标记,即使缓冲区的数据没有超过水位线,也会向上层交付数据。
- RST:当通信时一端发现了异常,就会发送带有RST标记的报文要求重新建立连接
- SYN:SYN标记为1,表明是一个连接请求的报文;只有请求建立连接时才会有标记为1,正常通信时SYN不会被设置。
- FIN:FIN标记为1,表明是一个断开连接的报文,正常通信的报文不会设置FIN标记位。
- 16位窗口大小:每次发送报文时,都会向对方更新当前本机的接收缓冲区的接收能力,以达到动态控制双方报文的发送量;窗口最大也就是64KB。但选项报头中可以设置窗口因子,以设置更大的窗口大小。
- 校验和:检测在数据传输过程中是否出现了错误或被篡改,保证数据完整性和准确性。
二、三次握手
为了确保TCP通信时的可靠性,TCP协议要求TCP双方在通信前建立一条可靠的通信连接,通过这条连接,通信双方可以确认对方的存在和可用性,并且数据能够正确的传输和接收,三次握手就是为了建立一条可靠连接!
- 第一次握手:A主机向B主机发送标记了SYN的报文,表明请求建立连接
- 第二次握手:B主机向A主机发送SYN和ACK标记的报文,表明接受建立连接的请求,并等待A确认连接;B开始时处于listen状态,A的连接请求会放在主机B的accept队列中,等到B的处理
- 第三次握手:A发送ACK报文表示确认连接
需要注意的是,A主机在第三次发送ACK报文时就已经建立好了连接处于ESTABLISHED状态,而B是在收到了A的ACK报文时才会建立连接处于ESTABLISHED状态。
三次握手确保了双发都有收发数据的能力;当A收到第二次握手的报文时,A就确定了自己发送的报文对方能收到,但此时B并不清楚自己发出去的报文A是否能收到,只有当B收到第三次握手的报文时,B也确定了自己发送的报文对方能收到,此时就确保了双向信道的可靠性。
所以一次、两次握手是不可行的,三次握手是确保全双工可靠通信的最小成本;当然了,三次握手都可以,四次握手当然也能确保建立一条可靠连接了,其实三次握手中的第二次握手的报文是捎带应答了,不然确实就是四次握手了。
三次握手期间,顺便进行了序号协商和窗口更新的操作,在后续正常通信中,确保数据的按序交付和实现流量控制。 这是后续TCP协议高效、可靠传输数据的关键环节。
三、数据传输
TCP经过三次握手建立连接后,就可以正常的收发数据了
- 发送数据:TCP在发送缓冲区的滑动窗口中,选择还未发送的数据,对数据分包并添加报头,交给下层的IP层去发送
- 接收数据:TCP收到数据后,会根据报头中的序号给多个报文中的数据排序,去掉报头,放在接收缓冲区中,并根据收到的数据的字节序设置确认序号,向发送方发送应答报文。
- 超时重传:当发送方以往发送的报文在一定时间后没有收到应答报文,会触发超时重传机制
在主机A发送一个报文后,会启动一个计时器,计时到期还没收到应答报文就会再次重发数据包
- 滑动窗口机制:
滑动窗口内的数据,可以直接封装报头发送,暂时不需要对方应答,从而实现并发的发送大量报文。
双方都维护一个窗口大小,并在报文中更新;窗口中的数据可以直接发送,待收到应答后在移除窗口,已发送未确认的数据后来要么因为收到应答报文被移除,要么因为触发超时重传或快速重传被再次发送;双方通过报文中对方的窗口大小和网络负载情况动态的调整自己的窗口大小。
win_stat = 最新收到的确认序号
win_end = min(对方窗口,拥塞窗口)
以此实现流量控制,在网络环境良好的情况下,根据对方的接收能力来决定发送报文的多少;与此同时,拥塞窗口一直在探测网络环境,当出现网络拥塞时,以网络环境为主,少量的发送报文继续下一轮网络环境的探测。
- 拥塞控制算法:Reno(慢启动、拥塞避免、快速重传、快速恢复)
TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据;像上面这样的拥塞窗口增长速度, 是指数级别的. "慢启动" 只是指初使时慢, 但是增长速度非常快。
TCP会预设一个慢启动阈值,当拥塞窗口窗口这一值时,会从指数增长变为线性增长,进入拥塞避免阶段;如图就是发送端每收到8个应答拥塞窗口就增加1,以此继续线性增长以探测网络环境,当网络环境拥塞时,会根据严重程度处理拥塞窗口的变化逻辑。一般而言,超时丢包是比较严重的,说明网络拥塞比较严重,TCP会更新为慢启动模式,将慢启动阈值设为当前拥塞窗口的一半
如果是收到三次同样的ACK报文,则说明是某一个数据包丢失,此时网络是轻微拥塞,没必要大幅调整拥塞窗口,会使用快速重传和快速恢复算法:
四、四次挥手
TCP是全双工的,两个方向可以同时传输数据,因此,两个方向都需要单独关闭。
A主机在数据发送结束后,发送一个FIN的报文来终止A--->B方向的传输,待B主机应答后进入半关闭状态(不能再主动发数据);B主机检查自己的数据是否发送完毕,若未完成则继续发送,直到完成后发送一个FIN来终止传输,在收到A的应答后关闭整个连接。
需要注意的是:主动关闭的一方,响应最后一个ACK报文后,会进入TIME_WAIT状态,而被动关闭的一方在收到应答报文后会直接关闭。
这是因为:
确保最后一个 ACK 能被对方收到
假设主动关闭方发送的最后一个 ACK 丢失了,被动关闭方会因为没有收到 ACK 而重传 FIN 报文。如果主动关闭方没有处于 TIME_WAIT 状态而是直接关闭,就无法响应重传的 FIN 报文,导致被动关闭方不能正常关闭连接。允许老的重复分节在网络中消逝
TCP 连接可能会因为网络延迟等原因出现数据包延迟到达的情况。如果新的连接使用了与刚刚关闭的连接相同的端口和 IP 地址,而延迟的旧数据包到达,可能会造成数据混乱。通过在 TIME_WAIT 状态等待一段时间,可以确保这些延迟的数据包在新连接建立之前已经消失,避免对新连接产生影响。
以下是从连接建立到正常通信,再到连接关闭的状态示意图:
相关文章:

TCP 通信全流程分析:从连接建立到数据传输的深度探索
目录 一、TCP报头 二、三次握手 三、数据传输 四、四次挥手 本文通过一次TCP通信过程的分析来学习TCP协议 一、TCP报头 如图是一份TCP报文的报头,标准报头是20个字节,还可带有选项报头,也就是TCP报头的最小长度是20字节。以下是对报头的各…...
4、提取H264码流中nalu
H264的NALU提取 1、nalu单元 定义nalu的存储单元,ebsp用来存储原始的包含起始码(annexb格式)的原始码流,sodb存储去除防竞争字节后的码流,prefix是3或4字节 nalu_def.h // nalu_def.h #pragma once#include <cs…...

哈佛大学单细胞课程|笔记汇总 (二)
哈佛大学单细胞课程|笔记汇总 (一) (二)Single-cell RNA-seq data - raw data to count matrix 根据所用文库制备方法的不同,RNA序列(也被称为reads或tag)将从转录本((10X Genomic…...
java中抽象类和接口的区别
文章目录 接口和抽象类的区别一、定义的区别1、抽象类2、接口 二、使用场景的区别1、抽象类2、接口 三、使用案例1、抽象类2、接口 接口和抽象类的区别 一、定义的区别 1、抽象类 关键字: abstract 是模棱两可的,似是而非的,无法给出具体明…...

Spring Boot - 在Spring Boot中实现灵活的API版本控制(下)_ 封装场景启动器Starter
文章目录 Pre设计思路ApiVersion 功能特性使用示例配置示例 ProjectStarter Code自定义注解 ApiVersion配置属性类用于管理API版本自动配置基于Spring MVC的API版本控制实现WebMvcRegistrations接口,用于自定义WebMvc的注册逻辑扩展RequestMappingHandlerMapping的类…...

EasyCVR视频转码:T3视频平台不支持GB28181协议,应该如何实现与视频联网平台的对接与视频共享呢?
EasyCVR视频管理系统以其强大的拓展性、灵活的部署方式、高性能的视频能力和智能化的分析能力,为各行各业的视频监控需求提供了优秀的解决方案。 T3视频为公网HTTP-FLV或HLS格式的视频流,目前T3平台暂不支持国标GB28181协议,因此也无法直接接…...
Spring统一处理请求响应与异常
在web开发中,规范所有请求响应类型,不管是对前端数据处理,还是后端统一数据解析都是非常重要的。今天我们简单的方式实现如何实现这一效果 实现方式 定义响应类型 public class ResponseResult<T> {private static final String SUC…...
SqlServer公用表表达式 (CTE) WITH common_table_expression
SQL Server 中的公用表表达式(Common Table Expressions,简称 CTE)是一种临时命名的结果集,它在执行查询时存在,并且只在该查询执行期间有效。CTE 类似于一个临时的视图或者一个内嵌的查询,但它提供了更好的…...

常见中间件漏洞
Tomcat CVE-2017-12615 1.打开环境,抓包 2.切换请求头为 PUT,请求体添加木马,并在请求头添加木马文件名 1.jsp,后方需要以 / 分隔 3.连接 后台弱口令部署war包 1.打开环境,进入指点位置,账户密码均为 tomcat 2.在此处上传一句话…...

elasticsearch的学习(二):Java api操作elasticsearch
简介 使用Java api操作elasticsearch 创建maven项目 pom.xml文件 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi…...

docker 部署 ElasticSearch;Kibana
ELasticSearch 创建网络 docker network create es-netES配合Kibana使用时需要组网,使两者运行在同一个网络下 命令 docker run -d \ --name es \ -e "discovery.typesingle-node" \ -v /usr/local/es/data:/usr/share/elasticsearch/data \ -v /usr/…...

k8s使用kustomize来部署应用
k8s使用kustomize来部署应用 本文主要是讲述kustomzie的基本用法。首先,我们说一下部署文件的目录结构。 ./ ├── base │ ├── deployment.yaml │ ├── kustomization.yaml │ └── service.yaml └── overlays└── dev├── kustomization.…...

基于开源FFmpeg和SDL2.0的音视频解码播放和存储系统的实现
目录 1、FFMPEG简介 2、SDL简介 3、视频播放器原理 4、FFMPEG多媒体编解码库 4.1、FFMPEG库 4.2、数据类型 4.3、解码 4.3.1、接口函数 4.3.2、解码流程 4.4、存储(推送) 4.4.1、接口函数 4.4.2、存储流程 5、SDL库介绍 5.1、数据结构 5.…...

保姆级教程,一文了解LVS
目录 一.什么是LVS tips: 二.优点(为什么要用LVS?) 三.作用 四.程序组成 五.LVS 负载均衡集群的类型 六.分布式内容 六.一.分布式存储 六.二.分布式计算 六.三.分布式常见应用 tips: 七.LVS 涉及相关的术语 八.LVS 负…...

【STM32】DMA数据转运(存储器到存储器)
本篇博客重点在于标准库函数的理解与使用,搭建一个框架便于快速开发 目录 DMA简介 DMA时钟使能 DMA初始化 转运起始和终止的地址 转运方向 数据宽度 传输次数 转运触发方式 转运模式 通道优先级 开启DMA通道 DMA初始化框架 更改转运次数 DMA应用实例-…...
【Android】通过代码打开输入法
获取焦点 binding.editText.requestFocus()打开键盘 val imm getSystemService(InputMethodManager::class.java) imm.showSoftInput(binding.editText, InputMethodManager.SHOW_IMPLICIT)...
爬虫集群部署:Scrapyd 框架深度解析
🕵️♂️ 爬虫集群部署:Scrapyd 框架深度解析 🛠️ Scrapyd 环境部署 Scrapyd 是一个开源的 Python 爬虫框架,专为分布式爬虫设计。它允许用户在集群中调度和管理爬虫任务,并提供了简洁的 API 进行控制。以下是 Scr…...
pytorch GPU操作事例
>>> import torch >>> if_cuda torch.cuda.is_available() >>> print("if_cuda",if_cuda) if_cuda True >>> gpu_count torch.cuda.device_count() >>> print("gpu_count",gpu_count) gpu_count 8...

linux常见性能监控工具
常用命令top、free 、vmsata、iostat 、sar命令 具体更详细命令可以查看手册,这里只是简述方便找工具 整体性能top,内存看free,磁盘cpu内存历史数据可以vmsata、iostat 、sar、iotop top命令 交互:按P按照CPU排序,按M按照内存…...

C++ | Leetcode C++题解之第331题验证二叉树的前序序列化
题目: 题解: class Solution { public:bool isValidSerialization(string preorder) {int n preorder.length();int i 0;int slots 1;while (i < n) {if (slots 0) {return false;}if (preorder[i] ,) {i;} else if (preorder[i] #){slots--;i…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...