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 状态等待一段时间,可以确保这些延迟的数据包在新连接建立之前已经消失,避免对新连接产生影响。

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

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

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

相关文章

千里江山图,自动化成诗:Expect脚本详解——从入门到进阶的自动化利器

目录 引言 Expect脚本基础 什么是Expect 基本语法 进阶应用 错误处理 正则表达式 并发处理 使用Shell脚本管理多个Expect脚本 在Expect脚本内部模拟并发 脚本复用与模块化 总结 引言 在自动化运维和测试领域,Expect脚本无疑是一把强大的利器。它以其灵…

鸿蒙Image组件设置长按手势回调事件

Image组件默认是可拖拽的,给Image组件设置draggable为false,即可成功触发长按事件:

基于Hadoop的北京市二手房价数据分析与可视化

文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主项目介绍总结每文 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主 项目介绍 随着中国经济的快速发展和城市化进程的加速,房地产市场已成为国民经…

难题:反转链表

定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。 思考题: 请同时实现迭代版本和递归版本。 数据范围 链表长度 [0,30]。 样例 输入:1->2->3->4->5->NULL输出:5->4->3->2->1->N…

sgetrf M N is 103040 时报错,这是个bug么 lapack and Openblas the same,修复备忘

1,现象 MN103040时,调用 sgetrf_ 时,无论是 LAPACK 还是 OpenBLAS,都出错: openblas: lapack: 2, 复现代码 出现问题的应该是由于M和N相对数字太大,乘积超出32bit整数的表达范围,…

vulnhub靶机tomato记录

https://www.vulnhub.com/entry/tomato-1,557/ 过程 用nmap对目标主机做全端口扫描,dirb做目录扫描,结果如下: 8888端口开放一个web服务,存在Basic认证,试了爆破无果,sun-answerbook是一个在线文档系统&am…

门店收银系统源码+同城即时零售多商户入驻商城源码

一、我们为什么要开发这个系统? 1. 商户经营现状 “腰尾部”商户,无小程序运营能力;自营私域商城流量渠道单一;无法和线下收银台打通,库存不同步,商品不同步,订单不同步; 2.平台服…

MongoDB学习记录

1、初识Mongo 概述:与关系型数据库不同,MongoDB 的数据以类似于 JSON 格式的二进制文档存储,通常称这种格式为Bson,Bson不仅支持JSON中已有的数据类型,还增加了一些额外的数据类型,例如日期和二进制数据&a…

python爬虫学习记录-请求模块urllib3

(文章内容仅作学习交流使用) urllib3是一个功能强大、条理清晰,用于HTTP客户端的第三方模块 urllib3-发送网络请求 使用urllib3发送网络请求时,需要先创建PoolManager对象,并使用该对象的request方法发送请求&#…

[Spring] Spring AOP

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…

Qt实现类似淘宝商品看板的界面,带有循环翻页以及点击某页跳转的功能

效果如下&#xff1a; #ifndef ModelDashboardGroup_h__ #define ModelDashboardGroup_h__#include <QGridLayout> #include <QLabel> #include <QPushButton> #include <QWidget>#include <QLabel> #include <QWidget> #include <QMou…

扩展【从0制作自己的ros导航小车】C++_ROS_QT5联合编译,简单界面为ROS开发增添交互

从0制作自己的ros导航小车 前言一、环境搭建二、联合编译三、测试 前言 前面已经实现了导航功能&#xff0c;对于之后的一些开发&#xff0c;有交互能力是比较重要的&#xff0c;比如小车上连接一块屏幕&#xff0c;通过屏幕来选择模式&#xff0c;可视化等等。QT是不错的选择…

LVS是什么?以及LVS-NAT以及DR模式实验

目录 NAT LVS LVS集群的类型&#xff1a; LVS-NAT模式实验 环境准备&#xff1a; 实验步骤&#xff1a; LVS-DR模式实验 题目&#xff1a; 环境准备&#xff1a; 实验步骤&#xff1a; LVS-防火墙标签解决轮询调度问题 环境准备&#xff1a; 实验步骤&#xff1…

智界S7 小鹏P7 G3 G3i P5 G9 P7i G6 X9维修手册和电路图线路图接线资料更新

汽修帮手资料库提供各大厂家车型维修手册、电路图、新车特征、车身钣金维修数据、全车拆装、扭力、发动机大修、发动机正时、保养、电路图、针脚定义、模块传感器、保险丝盒图解对照表位置等&#xff0c;并长期保持高频率资料更新&#xff01; 覆盖车型2020-2024年智界S7 小鹏…

在VScode中导入conda环境的记录【原创】

今天在vscode编辑器中运行一个python代码&#xff0c;发现终端可以运行&#xff0c;但是编辑器中点击Run会显示缺包&#xff0c;但是python包明明是有的&#xff0c;在自己的conda环境中。后来发现&#xff0c;是vscode没有发现我自己创建的conda环境&#xff0c;在vscode中导入…

51单片机个人学习笔记16(红外遥控)

前言 本篇文章属于STC89C52单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 [1-1] 课程简介_哔哩…

Java封装原生ES

文章目录 &#x1f31e; Sun Frame&#xff1a;SpringBoot 的轻量级开发框架&#xff08;个人开源项目推荐&#xff09;&#x1f31f; 亮点功能&#x1f4e6; spring cloud模块概览常用工具 &#x1f517; 更多信息1.spring-data-es操作ES1.引入依赖2.application.yml配置uris3…

高频焊接设备配电系统无源滤波系统的设计

1、高频焊机系统谐波状况简介 变压器容量&#xff1a;S11-M-1600/10KVA&#xff08;105%&#xff09;/0.4KV 短路阻抗&#xff1a;3.9% 谐波负载情况&#xff1a;一台600KW高频焊接设备 型号&#xff1a;GGP600-0.3-HC 输入电压&#xff1a;380V 输出电压&#xff1a;0…

【Python机器学习】回归——示例:预测乐高玩具套装的价格

用回归法预测乐高套装价格的基本步骤&#xff1a; 1、收集数据&#xff1a;用Google Shopping的API收集到的数据 2、准备数据&#xff1a;从返回的JSON数据中抽取价格 3、分析算法&#xff1a;可视化并观察数据 4、训练算法&#xff1a;构建不同的模型&#xff0c;采用逐步线性…

操作ArkTS页面跳转及路由相关心得

本文为JS老狗原创。 当前端不得不关注的点&#xff1a;路由&#xff0c;今天聊一聊鸿蒙相关的一点心得。 总体上套路不意外&#xff0c;基本就是&#xff08;尤其是Web&#xff09;前端那些事&#xff1a;维护路由表、跳转带参数、历史堆栈操作&#xff0c;等等。 历史原因&…