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

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状态,而被动关闭的一方在收到应答报文后会直接关闭。

这是因为:

  1. 确保最后一个 ACK 能被对方收到
    假设主动关闭方发送的最后一个 ACK 丢失了,被动关闭方会因为没有收到 ACK 而重传 FIN 报文。如果主动关闭方没有处于 TIME_WAIT 状态而是直接关闭,就无法响应重传的 FIN 报文,导致被动关闭方不能正常关闭连接。

  2. 允许老的重复分节在网络中消逝
    TCP 连接可能会因为网络延迟等原因出现数据包延迟到达的情况。如果新的连接使用了与刚刚关闭的连接相同的端口和 IP 地址,而延迟的旧数据包到达,可能会造成数据混乱。通过在 TIME_WAIT 状态等待一段时间,可以确保这些延迟的数据包在新连接建立之前已经消失,避免对新连接产生影响。

以下是从连接建立到正常通信,再到连接关闭的状态示意图:

相关文章:

TCP 通信全流程分析:从连接建立到数据传输的深度探索

目录 一、TCP报头 二、三次握手 三、数据传输 四、四次挥手 本文通过一次TCP通信过程的分析来学习TCP协议 一、TCP报头 如图是一份TCP报文的报头,标准报头是20个字节,还可带有选项报头,也就是TCP报头的最小长度是20字节。以下是对报头的各…...

4、提取H264码流中nalu

H264的NALU提取 1、nalu单元 定义nalu的存储单元&#xff0c;ebsp用来存储原始的包含起始码&#xff08;annexb格式&#xff09;的原始码流&#xff0c;sodb存储去除防竞争字节后的码流&#xff0c;prefix是3或4字节 nalu_def.h // nalu_def.h #pragma once#include <cs…...

哈佛大学单细胞课程|笔记汇总 (二)

哈佛大学单细胞课程|笔记汇总 &#xff08;一&#xff09; &#xff08;二&#xff09;Single-cell RNA-seq data - raw data to count matrix 根据所用文库制备方法的不同&#xff0c;RNA序列&#xff08;也被称为reads或tag&#xff09;将从转录本&#xff08;(10X Genomic…...

java中抽象类和接口的区别

文章目录 接口和抽象类的区别一、定义的区别1、抽象类2、接口 二、使用场景的区别1、抽象类2、接口 三、使用案例1、抽象类2、接口 接口和抽象类的区别 一、定义的区别 1、抽象类 关键字&#xff1a; abstract 是模棱两可的&#xff0c;似是而非的&#xff0c;无法给出具体明…...

Spring Boot - 在Spring Boot中实现灵活的API版本控制(下)_ 封装场景启动器Starter

文章目录 Pre设计思路ApiVersion 功能特性使用示例配置示例 ProjectStarter Code自定义注解 ApiVersion配置属性类用于管理API版本自动配置基于Spring MVC的API版本控制实现WebMvcRegistrations接口&#xff0c;用于自定义WebMvc的注册逻辑扩展RequestMappingHandlerMapping的类…...

EasyCVR视频转码:T3视频平台不支持GB28181协议,应该如何实现与视频联网平台的对接与视频共享呢?

EasyCVR视频管理系统以其强大的拓展性、灵活的部署方式、高性能的视频能力和智能化的分析能力&#xff0c;为各行各业的视频监控需求提供了优秀的解决方案。 T3视频为公网HTTP-FLV或HLS格式的视频流&#xff0c;目前T3平台暂不支持国标GB28181协议&#xff0c;因此也无法直接接…...

Spring统一处理请求响应与异常

在web开发中&#xff0c;规范所有请求响应类型&#xff0c;不管是对前端数据处理&#xff0c;还是后端统一数据解析都是非常重要的。今天我们简单的方式实现如何实现这一效果 实现方式 定义响应类型 public class ResponseResult<T> {private static final String SUC…...

SqlServer公用表表达式 (CTE) WITH common_table_expression

SQL Server 中的公用表表达式&#xff08;Common Table Expressions&#xff0c;简称 CTE&#xff09;是一种临时命名的结果集&#xff0c;它在执行查询时存在&#xff0c;并且只在该查询执行期间有效。CTE 类似于一个临时的视图或者一个内嵌的查询&#xff0c;但它提供了更好的…...

常见中间件漏洞

Tomcat CVE-2017-12615 1.打开环境&#xff0c;抓包 2.切换请求头为 PUT&#xff0c;请求体添加木马&#xff0c;并在请求头添加木马文件名 1.jsp&#xff0c;后方需要以 / 分隔 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使用时需要组网&#xff0c;使两者运行在同一个网络下 命令 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的基本用法。首先&#xff0c;我们说一下部署文件的目录结构。 ./ ├── 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、存储&#xff08;推送&#xff09; 4.4.1、接口函数 4.4.2、存储流程 5、SDL库介绍 5.1、数据结构 5.…...

保姆级教程,一文了解LVS

目录 一.什么是LVS tips: 二.优点&#xff08;为什么要用LVS&#xff1f;&#xff09; 三.作用 四.程序组成 五.LVS 负载均衡集群的类型 六.分布式内容 六.一.分布式存储 六.二.分布式计算 六.三.分布式常见应用 tips&#xff1a; 七.LVS 涉及相关的术语 八.LVS 负…...

【STM32】DMA数据转运(存储器到存储器)

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 DMA简介 DMA时钟使能 DMA初始化 转运起始和终止的地址 转运方向 数据宽度 传输次数 转运触发方式 转运模式 通道优先级 开启DMA通道 DMA初始化框架 更改转运次数 DMA应用实例-…...

【Android】通过代码打开输入法

获取焦点 binding.editText.requestFocus()打开键盘 val imm getSystemService(InputMethodManager::class.java) imm.showSoftInput(binding.editText, InputMethodManager.SHOW_IMPLICIT)...

爬虫集群部署:Scrapyd 框架深度解析

&#x1f575;️‍♂️ 爬虫集群部署&#xff1a;Scrapyd 框架深度解析 &#x1f6e0;️ Scrapyd 环境部署 Scrapyd 是一个开源的 Python 爬虫框架&#xff0c;专为分布式爬虫设计。它允许用户在集群中调度和管理爬虫任务&#xff0c;并提供了简洁的 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命令 具体更详细命令可以查看手册&#xff0c;这里只是简述方便找工具 整体性能top,内存看free&#xff0c;磁盘cpu内存历史数据可以vmsata、iostat 、sar、iotop top命令 交互&#xff1a;按P按照CPU排序&#xff0c;按M按照内存…...

C++ | Leetcode C++题解之第331题验证二叉树的前序序列化

题目&#xff1a; 题解&#xff1a; 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…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...