linux网络 | 传输层TCP | 认识tcp报头字段与分离

        前言: 本节内容继续传输层的讲解, 本节讲解的是tcp协议。 tcp协议是我们日常中最常用的协议。就比如我们浏览网页,我们知道网页时http或者https协议。 其实http或者https底层就是用的tcp协议。tcp协议,全名又称为传输控制协议,Translation Control protocol。现在为话不多说, 开始我们的学习吧!

        ps:关于讲解tcp, 仍旧采取和udp同样的策略。 先讨论tcp的报头和有效载荷如何分离, 然后讨论报头里面的内容, 最后是tcp的相关知识点。 本节内容是进入传输层tcp的第一节内容, 没有前置知识点, 友友们只要使用过tcp的socket相关接口就可以学习哦!

目录

为什么叫做TCP(传输控制协议)

TCP报头分离

十六位窗口大小 

流量控制

确认应答机制 

十六位窗口控件 

32位序号和32位确认序号  

捎带应答 

超时重传

32位序号 

32位确认序号 

为什么要有两种序号


为什么叫做TCP(传输控制协议)

        

        tcp协议在操作系统内部有一个叫做发送缓冲区,一个叫做接收缓冲区。然后平时我们在写代码的时候,我们自己在上层写的缓冲区,叫做用户缓冲区。

        我们平时使用的write,rev,read,send这些,本质上不是发送函数,而是拷贝函数。是将用户级缓冲区里面的内容,拷贝到内存级缓中区里面。至于数据什么时候发送,发送多少,出错了怎么办,由TCP协议自主决定。 这个就是自主控制,又因为它在传输层是来传输的, 所以就是传输控制。 

        这个知识点,就和我们之前学习文件是一样的,我们之前使用write,等接口,本质上就是把数据拷贝到内核的文件缓冲区里面。至于这个数据什么时候刷,刷多少,出错了怎么办,是由内核决定的。所以,从今天来看,磁盘和网络没有区别,只是将磁盘设备换成了网卡,就可以完成数据的IO,文件是IO,网络也是IO。下面这张图, 就是整个的传输控制过程:

        这里有个小的点就是关于全双工:tcp无论是客户端,还是服务端都能够接收和发送,这个过程,就叫做全双工。

TCP报头分离

        下面是整个的TCP报文。 

        十六位源端口号和十六位目的端口号,就知道我们要把数据交给哪个主机。

        标准报头是固定大小,固定20个字节。所以拿20个字节就是把标准报头全部拿到了。这个时候,就能拿到里面的一个字段:4位首部长度,标识报头的总长度是多少(标准 + 选项)。 四位首部长度长度最大范围是[0000, 1111], 也就是[0, 15]。 单位是4,也就是说, 四位首部长度的范围是[0, 60]。 所以, tcp报头最多是60字节, 标准占20, 所以选项最多就是40个。

        如果我们不谈选项,这个四位首部长度x * 4 = 20 ==> x = 5;也就是说0101, 那么四位首部长度最少就是0101。 最多是1111。另外,这里这个四位首部长度, 我们可以叫他自描述字段。 

        所以, 如何分离报头和报文, 就是:固定长度 + 自描述字段。

十六位窗口大小 

        我们第一个要谈的报头信息是十六位窗口大小。

        先说结论, 这个十六位窗口大小填写的是自己的接收缓冲区的大小。 

        为什么要有这个十六位窗口大小? 这个就涉及到了两个其他的知识点。 一个是‘流量控制’, 一个是‘确认应答’。下面我们来看一下这两个知识点:

流量控制

首先看一下流量控制

        首先我们先看一下客户端和服务端的报文交互:

        对于客户端和服务端来讲, 双方的任何通信, 都要有完整的报头, 就比如客户端发送一个你好,就要添加上完整的报头, 然后你好作为数据。 发送给服务端, 然后就写入了服务端的接收缓冲区。 服务端发送给客户端同样如此, 都是写入到客户端的接收缓冲区。

        但是, 有一个问题,我们的客户端向服务端发送请求的时候, 如果客户端请求发送的很快,服务端请求拿的很慢, 或者根本就不拿。 那么是不是就总是有一刻服务端的接收缓冲区被打满?服务端的接收缓冲区一旦被打满, 客户端如果再向服务端发送数据, 那么这些数据就写不进去, 就一定会出现大面积丢包的情况。所以, 客户端就要有手段能够降低发送请求的速度或者干脆不发了, 这种手段, 就叫做流量控制!!!

确认应答机制 

        什么是确认应答,就比如我们在和朋友在微信上面现天我们对我们的用友说,吃饭了吗。我们的朋友如果看到了,就会说:吃了。我们看到"吃了“,我们就知道对方看到了我们的消息,这就是确认应答。

        所以,确认应答机制, 就是:客户端向服务器发送任何请求、消息的时候,服务器都要向客户端进行响应。这样客户端就能保证,客户端到服务器方向的可靠性。相反,服务器向客户端发送的任何请求,客户端都响应,就能保证服务器到客户端方向的可靠性。

十六位窗口控件 

        客户端流量控制,发送的慢一点,依据是什么?对于发送方来说,发送的速度是由对方的接收缓冲区中剩余空间的大小来决定。问题是,我怎么知道对方的接收缓冲区中剩余的空间大小呢?别忘了,我们的tp是基于确认应答机制的,我们给服务端发送一个信息,对方就要返回给我们一个响应。对方给我们的响应里面又是包含完整的报头的! 报头里面又有一个16位窗口大小! 所以,这个16位窗口大小,填充的就是自身的接收缓冲区的剩余空间的大小!!! 

        所以, 下一个定义:16位窗口大小,填写的是自己的接收缓冲区中的大小!!  

32位序号和32位确认序号  

        在正式讲解这个报头字段之前先讨论两个小知识点:捎带应答和超时重传。

捎带应答 

什么是捎带应答,就是C或者S发了应答,又要发送tcp数据的时候,不再发送两次了,而是合成一份发送,这种情况下就叫做捎带应答。

        就类似于我们平时说话,你说吃了吗,朋友说吃了, 你吃了吗。 这种情况就是朋友将应答”吃了“和tcp数据”你吃了吗“合在了一起。即为捎带应答。

        另外一个知识点就是超时重传。

超时重传

        下面是tcp最基本, 最原本的通信过程:

        上面这种,一端发送数据,另一方进行应答。双方都发送数据,双方都进行应答,就能保证两个方向上的可靠性。
        另外,对于双方来说,如何确认一条消息对方没有收到呢?难道要一直等着对方的应答吗? 要知道,如果确认到对方没有收到应答后,就应该重传数据了。 所以一直等待对方的应答是不合理的。所以,一段时间后,如果没有收到应答,双方就会认为数据丢失,就要重新发送数据。——即为,超时重传。

 

32位序号 

        先来思考一下,世界上存不存在100%可靠的网络协议? 

        确认应答机制,有一个现象,就是我收到了应答,那么我就能保证应答之前的最新的发送的消息是被对方收到了。没有应答的数据,我们无法保证可靠性。
        所以,最新的一条消息,是没有应答的。在人类世界里,我们无法保证发送出去的消息是100%可靠的!所以,从全局的角度上,我们这个世界上是不存在100%可靠的协议的但是能保证局部上的消息的可靠性(最新消息之前的消息的可靠性。)

        一个发送,一个应答,效率是非常低下的。通常我们的客户端向服务器发消息,一次是发一批消息。

 

        但是, 这里有一个问题, 我们的服务器按顺序把它发出,服务器是否按顺序把它接受呢?

        就像一开始一群人在东北,现在要去广东。是否到达广东的顺序就是这群人离开东北的顺序呢。答案是不是的,有些人是坐飞机过去,有些人坐火车过去,有些人坐客车过去。有些人可能虽然出发的比较晚,但是人家是做飞机过去的,有些人虽然出发比较早,但是他是坐或者过去的。坐飞机的就有可能比坐火车的先到目的地。 

        所以,服务器按顺序发出信息,并不一定是按照顺序接收到。 这就导致了一个问题一一数据包乱序问题。

        乱序本身就是不可靠的一种,所以,每一个tcp报头里,会包含一个序号的东西一就是这个32位序号。这个32位序号,就是保证数据的按序到达。

         下面就是32位序号: 

32位确认序号 

        假如我今天一次给对方发送了多个报文,那么对方一定也要给我多个响应。我怎么知道响应对应的是哪一个报文呢?

        所以tcp为了区分响应对应的是哪一个报文的响应,就有了32位确认序号的概念。
        确认序号,填充的是,收到报文的序号 +1。
        为什么要这么规定,确认序号的意义: 表示确认序号之前的数据,我已经全部收到了!!!
        下一次发送请从确认序号指定的数字开始发送、就是说,客户端发送的序号是1000,那么服务端响应的序号就得是1001。
        这样做的意义是什么?
        这样做是为了允许应答有少量的丢失、就发送的数有100,200,300,那应只有3001,但是没有10012001但是不需要重传,默认就认为3001%前的报文全都响应了。

为什么要有两种序号

        我们知道,请求是有数据的,用的是32位序号,然后响应是没有数据的,用的是32位确认序号。但是,为什么不直接只使用32位序号或者32位确认序号呢?为什么非要用两种序号呢?
        原因就在于客户端给服务器发消息,服务器要给我应答,服务器应答,可能只是应答,也可能是指捎带应答。应答就是纯报头,只是用32位确认序号,捎带应答就是要有数据,并且捎带应答因为也有数据,所以就要有32位序号。也就是说,因为一个报文,他可能有双重身份,既可能是应答,也可能是带有数据,所以序号和确认序号有可能同时存在,所以协议里面必须把这两个分开,不能复用。 

 

  ——————以上就是本节全部内容哦, 如果对友友们有帮助的话可以关注博主, 方便学习更多知识哦!!!   

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

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

相关文章

Mysql触发器(学习自用)

一、介绍 二、触发器语法 注意:拿取新的数据时用new,旧数据用old。

ubuntu20使用apt安装mysql8

目录 ubuntu20使用apt安装mysql8报错列表参考链接首先删除旧mysql 一、下载配置mysql8库索引下载apt包解压包配置更新apt库索引 二、下载安装mysql8三、启动mysql服务配置开机自启动,忽略 本地登录远程登录查看mysql的所有用户使用客户端远程登陆如果报错完成 参考链…

昇腾AI产品

一.AI计算的基础知识 1.并行计算 指同时使用多种计算资源解决技术问题的过程,是提高计算机系统计算速度和数据处理能力的一种有效手段。它的基本思想是用多个处理器来共同求解同一个问题,即将被求解的问题分解成若干个部分,各部分均由一个独…

Linux内核编程(二十一)USB驱动开发-键盘驱动

一、驱动类型 USB 驱动开发主要分为两种:主机侧的驱动程序和设备侧的驱动程序。一般我们编写的都是主机侧的USB驱动程序。 主机侧驱动程序用于控制插入到主机中的 USB 设备,而设备侧驱动程序则负责控制 USB 设备如何与主机通信。由于设备侧驱动程序通常与…

学习Hibernate的调优方案

Hibernate是一个非常流行的Java ORM(对象关系映射)框架,它可以帮助开发者更轻松地处理数据库操作。然而,如果不进行适当的性能调优,Hibernate可能会导致应用程序运行缓慢。本文将详细探讨Hibernate的调优方案&#xff…

总结 uniapp 上不适配iphone的:new Date 时间、border线条、渐变

1、border样式缺了一边 这是错误样式: 需要添加: border: 1rpx solid #57c7bb; transform: rotateZ(0deg);//加入此代码解决iphone 不适配问题2、时间出现NaN 原因是因为ios中使用new Date 的时候出了问题 解决方案: 1.调整时间格式:将时间格式从"yyyy-MM-d…

内网渗透测试工具及渗透测试安全审计方法总结

1. 内网安全检查/渗透介绍 1.1 攻击思路 有2种思路: 攻击外网服务器,获取外网服务器的权限,接着利用入侵成功的外网服务器作为跳板,攻击内网其他服务器,最后获得敏感数据,并将数据传递到攻击者&#xff0…

Dockerfile另一种使用普通用户启动的方式

基础镜像的Dockerfile # 使用 Debian 11.9 的最小化版本作为基础镜像 FROM debian:11.11# 维护者信息 LABEL maintainer"caibingsen" # 复制自定义的 sources.list 文件(如果有的话) COPY sources.list /etc/apt/sources.list # 创建…

力扣707题——设计链表

#题目 从零开始设计链表,我们拆分成两次任务,今天先看1 ,2 ,4 #代码

leetcode刷题记录(七十二)——146. LRU 缓存

(一)问题描述 146. LRU 缓存 - 力扣(LeetCode)146. LRU 缓存 - 请你设计并实现一个满足 LRU (最近最少使用) 缓存 [https://baike.baidu.com/item/LRU] 约束的数据结构。实现 LRUCache 类: * LRUCache(int capacity)…

微信小程序:实现单选,多选,通过变量控制单选/多选

一、实现单选功能 微信小程序提供了 radio 组件来实现单选功能。radio 组件需要配合 radio-group 使用。 1. WXML 代码 <radio-group bindchange"onRadioChange"><label wx:for"{{items}}" wx:key"id"><radio value"{{it…

vue2使用flv.js在浏览器打开flv格式视频

组件地址&#xff1a;GitHub - bilibili/flv.js: HTML5 FLV Player flv.js 仅支持 H.264 和 AAC/MP3 编码的 FLV 文件。如果视频文件使用了其他编码格式就打不开。 flv.vue <template><div><el-dialog :visible.sync"innerVisibleFlv" :close-on-pre…

Spring 中的事件驱动模型

事件驱动的基本了解 事件模式也就是观察者模式&#xff0c;当一个对象改变的时候&#xff0c;所有依赖的对象都会收到一个通知。 Subject&#xff1a;抽象主题 Observer&#xff1a;具体主题 Concrete Subject&#xff1a;抽象观察者&#xff0c;在得到更新通知之后去更新自…

STM32补充——IAP

0 前置知识&#xff1a; FLASH相关内容&#xff1a;前往STM32补充——FLASH STM32三种烧录方式&#xff08;看看就行&#xff09;&#xff1a; 1.ISP&#xff1a;In System Programming&#xff08;在系统编程&#xff09; 执行芯片厂商的 Bootloader 程序进入 ISP 模式&…

k8s的CICD实施项目

环境需求&#xff1a; 目前领导需要做一个需求&#xff0c;临时把我从运维岗位&#xff0c;把我调度到到专家组让我主导cicd的项目实施 目前环境资源 k8s环境&#xff0c;28台服务器&#xff0c;上面是k8s集群&#xff0c;要实施一个测试环境的cicd以及一个生产环境的cicd gitl…

【线性代数】基础版本的高斯消元法

[精确算法] 高斯消元法求线性方程组 线性方程组 考虑线性方程组&#xff0c; 已知 A ∈ R n , n , b ∈ R n A\in \mathbb{R}^{n,n},b\in \mathbb{R}^n A∈Rn,n,b∈Rn&#xff0c; 求未知 x ∈ R n x\in \mathbb{R}^n x∈Rn A 1 , 1 x 1 A 1 , 2 x 2 ⋯ A 1 , n x n b 1…

AIGC视频生成模型:Runway的Gen系列模型

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍Runway开发的视频生成模型Gen系列&#xff0c;包括Gen-1、Gen-2和Gen3 Alpha等&#xff0c;这些模型每次发布都震惊AI圈&#xff0c;荣获多个视频生成的…

【JVM-9】Java性能调优利器:jmap工具使用指南与应用案例

在Java应用程序的性能调优和故障排查中&#xff0c;jmap&#xff08;Java Memory Map&#xff09;是一个不可或缺的工具。它可以帮助开发者分析Java堆内存的使用情况&#xff0c;生成堆转储文件&#xff08;Heap Dump&#xff09;&#xff0c;并查看内存中的对象分布。无论是内…

【基于无线电的数据通信链】Link 11 仿真测试

〇、废话 Link 11 仿真测试 涉及多个方面&#xff0c;包括信号仿真、协议模拟、数据链路层的仿真以及网络性能评估等。Link 11 是一种基于 HF&#xff08;高频&#xff09; 或 UHF&#xff08;超高频&#xff09; 波段的无线通信协议&#xff0c;主要用于军事通信系统中。为了…

AG32 FPGA 的 Block RAM 资源:M9K 使用

1. 概述 AG32 FPGA 包含了 4 个 M9K 块&#xff0c;每个 M9K 块的容量为 8192 bits&#xff0c;总计为 4 个 M9K&#xff08;4K bytes&#xff09;。这使得 AG32 的内部存储非常适合嵌入式应用&#xff0c;能够有效地利用片上资源。 M9K 参数 参考自《AGRV2K_Rev2.0.pdf》。…