深入理解TCP网络协议(3)

目录

1.前言

2.流量控制

2.阻塞控制

3.延时应答

4.捎带应答

5.面向字节流

6.缓冲区

7.粘包问题

8.TCP异常情况

9.小结


1.前言

   在前面的博客中,我们重点介绍了TCP协议的一些属性,有连接属性的三次握手和四次挥手,还有保证数据安全的重传机制和确认应答,还有为了提高效率所用的滑动窗口等.然而TCP协议的特性远不止这些,在这篇博客中,我们将更深入的了解决TCP协议的其它特性.

2.流量控制

  滑动窗口我们知道是用来提升传输效率的,这个窗口如果越大的话,那么自然传输效率也就越高,那么这个窗口可以无限增大吗?答案是否定的,首先从接收方的角度来看,接收方是有接收缓冲区的,如果这个窗口过大,发的数据过多,极有可能把这个缓冲区占满,那么就会引起一系列的问题.站在发送方的角度来看,也不能一次发送太多数据,因为我们不知道路上的网络线路是否通畅,能不能一次承担这么多的数据而不损失稳定性(这个我们一会在介绍).

   首先我们站在接收方的角度,其实接收方返回给发送方的ACK报头里面,是有一个窗口大小属性的,这个属性的大小取决于接收缓冲区剩余的内存大小.我们来画图说明一下.

有了接收方这个窗口大小这个字段,发送方就知道自己一次性发送多大的数据合适,就可以进行不影响可靠性的前提下提升效率了.

2.阻塞控制

在前面我们提到过,不仅仅是接收方要进行流量控制,告诉发送方要发多大的.在发送方这里,由于物理线路的影响,我们也得知道我们发送多大的合适,那么在TCP协议里,是如何知道网络的情况,以决定我们发送多大的数据合适呢?

这就要讲到我们的阻塞控制了.  我先来说一下基本的原理,我们可以先呈指数倍的发送数据,看有没有ack响应,如果都没问题的话,到了一定的阈值,我们可以在逐渐增大,一直到有数据丢失了(即没有收到ack,说明网络线路出问题了,可能到了它能承受的最大值,我们就接着降下去,在逐渐增大. 这是一个动态平衡的过程.这种思绪想是一种实验的方式来测试.

 当TCP开始启动的时候,慢启动阈值等于窗口最大值;
在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置回1;
少量的丢包,我们仅仅是触发超时重传;大量的丢包,我们就认为网络拥塞;
当TCP通信开始后,网络吞吐量会逐渐上升;随着网络发生拥堵,吞吐量会立刻下降;
拥塞控制,归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案

还有一个问题就是,我们到底是根据发送方的阻塞控制来确定窗口大小,还是根据接收方的流量控制来决定呢?

事实是,哪个小我们就遵守哪个.有点类似于木桶效应

3.延时应答

 如果接受数据的时候立即响应ack,这时候返回的窗口可能就比较小,为了解决这种问题.TCP协议内部还有一个延时应答的机制.

假设接收端缓冲区为1M。一次收到了500K的数据;如果立刻应答,返回的窗口就是500K;
但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了;
在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过
来;
如果接收端稍微等一会再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是
1M
事实上,这个时间的延时在用户眼里是非常小的,所以我们完全可以为了提升传输效率(返回的窗口大一些)使用延时应答机制.我们的目的是确保网络不拥堵的情况下,尽量提高传输效率.

那么所有的包都可以延迟应答么?肯定也不是;
数量限制:每隔N个包就应答一次;
时间限制:超过最大延迟时间就应答一次;
具体的数量和超时时间,依操作系统不同也有差异;一般N取2,超时时间取200ms

4.捎带应答

在延迟应答的基础上,我们发现,很多情况下,客户端服务器在应用层也是 "一发一收" 的。意味着客户端给服务器说了 "are  you ok?",服务器也会给客户端回一个 "very ok";
那么这个时候ACK就可以搭顺风车,和服务器回应的 "very ok" 一起回给客户端
 

5.面向字节流

TCP协议发送和接收的数据都是面向字节流的,我们可以给它传入一个byte数组,把我们想要的数据给转化成二进制的形势发送过去.接收的时候在转成对应的格式即可.

6.缓冲区

创建一个TCP的socket,同时在内核中创建一个 发送缓冲区 和一个 接收缓冲区;
调用write时,数据会先写入发送缓冲区中;
如果发送的字节数太长,会被拆分成多个TCP的数据包发出;
如果发送的字节数太短,就会先在缓冲区里等待,等到缓冲区长度差不多了,或者其他合适
的时机发送出去;
接收数据的时候,数据也是从网卡驱动程序到达内核的接收缓冲区;
然后应用程序可以调用read从接收缓冲区拿数据;
另一方面,TCP的一个连接,既有发送缓冲区,也有接收缓冲区,那么对于这一个连接,既
可以读数据,也可以写数据。这个概念叫做 全双工
由于缓冲区的存在,TCP程序的读和写不需要一一匹配,例如:
写100个字节数据时,可以调用一次write写100个字节,也可以调用100次write,每次写一
个字节;
读100个字节数据时,也完全不需要考虑写的时候是怎么写的,既可以一次read 100个字
节,也可以一次read一个字节,重复100次


7.粘包问题

TCP协议没有像UDP 一样有一个报文长度这样的字段,但是有一个序号这个字段.在传输层的角度,TCP报文是一个一个传输过来的,排列好的数据在缓冲区中,但是在应用层的角度,只是看到了一连串的字节数据,那么应用层看到的这些数据,就不知道应该从哪一部分到哪一步部分是一块的, 是不是一个完整的应用层数据报.

如何解决这个问题呢?我们三种方案

1.对于定包的长,我们每次都读取固定大小的的数据即可,

2.对于边长的包,我们可以在包头设置一个总包长度的字段,从而就知道了包结束的位置.

3.我们也可以在包和包中间使用明确的分隔符(应用层协议是程序员自己约定的,只要不影响数据,即正文的数据不和这个分隔符冲突久可.

粘包问题只是在TCP协议中会出现,并不会在UDP中出现,这是因为UDP是把英国摇滚乐数据交给应用层,要么收到完整的数据报,要么不收,不会出现半个的问题.所以不会有粘包问题.

8.TCP异常情况

我们知道TCP是有连接的,那么在出现异常的时候,TCP是如何断开连接的呢?我们分别来说明

进程中止:进程中止会释放文件描述符,仍然可以发送断开连接的FIN,和正常关闭没啥区别.

机器重启:重启的时候也会释放文件描述符,所以和进程中止的情况一样.

机器断网/断电:

1.如果断电的是接受方,发送方会发现没有ack了,会重传,重传几次还是不行, 就会进行复位操作,(相对于清楚原来的TCP中的临时数据重新开始)会用到RST这个复位报文段(和ack,fin,syn这些一样的报文段,另外,PSH是催促对方快点给我发消息,URG是TCP外带数据,语言写特殊的数据报会携带一些特殊功能的数据)  此时是RST也不会有ack,这个时候发送方就会单方面放弃连接.

2.如果是发送方接收了,发送方迟迟等不到数据,他会发送一个"心跳包",来询问对方的情况,如果这个"心跳包"一直没有得到回应,自然也会单方面释放连接了,这个心跳包是一个周期性的,如果没有心跳就会认为对端挂了,在以后的分布式系统中,服务器之间的互相调用也需要心跳包来确定存货状态.

9.小结

其实TCP协议非常复杂,它不仅仅是有我们前面几篇博客和这篇博客中强调的特性,还有其它的特性,希望各位大佬程序员这条路的修炼中,刻苦钻研,努力发掘.让自己的技术和对底层的 理解更上一层楼.

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

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

相关文章

vue3 之 组合式API—watch函数

watch函数 作用:侦听一个或者多个数据的变化,数据变化时执行回调函数 两个额外参数: 1.immediate(立即执行)2.deep(深度侦听) 场景:比如选择不同的内容请求后端不同数据时 如下图 …

重写Sylar基于协程的服务器(4、协程调度模块的设计)

重写Sylar基于协程的服务器(4、协程调度模块的设计) 重写Sylar基于协程的服务器系列: 重写Sylar基于协程的服务器(0、搭建开发环境以及项目框架 || 下载编译简化版Sylar) 重写Sylar基于协程的服务器(1、日…

华为机考入门python3--(8)牛客8-合并表记录

分类:字典排序 知识点: 将输入转成int的列表 my_list list(map(int, input().strip().split( ))) 将列表转为元组 tuple(my_list) 访问元素为元组的列表 for first, second, third in my_list: 对字典进行排序 sorted(my_dict.items())…

负载均衡下的webshell上传+nginx解析漏洞

负载均衡下的webshell上传 一,负载均衡下webshell上传的四大难点 难点一:需要在每一台节点的相同位置上传相同内容的webshell 我们需要在每一台节点的相同位置都上传相同内容的 WebShell一旦有一台机器上没有,那么在请求轮到这台机器上的时…

处理SERVLET中的错误

处理SERVLET中的错误 问题陈述 一位用户在使用在线计算机应用程序时输入一个非数字字符做数字加法。servlet试图将用户输入的值转换成整数型时,引发了NumberFormException类型的异常。要创建一个Web应用程序来使用自定义错误页面处理该异常。该自定义错误页面需要向用户提供关…

【Linux】Ext2 文件系统

文件系统 前言一、磁盘硬件1. 磁盘的物理存储结构2. 磁盘存储的逻辑抽象结构 二、理解 Ext2 文件系统1. 初步理解文件系统2. 深入理解文件系统(1)inode Table(2)Data blocks(3)inode Bitmap(4&a…

【Vue】2-9、Vue-CLI 脚手架

一、单页面程序 什么是单页面程序? 单页面程序(Single Page Application)简称 SPA,顾名思义,指的是一个 Web 网站中只有唯一一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成。 二、Vue-CLI …

万能写作辅助器设计

为了构建一个万能写作辅助器,我们需要设计几个关键组件,每个组件都有其特定的功能和交互方式。以下是这些组件的详细设计和描述: 对话生成器(Dialogue Generator) 功能:生成对话内容。输入:可接受拖拽过来的组件,如角色名称、情感标签、场景描述等。管理:能够管理各种…

【学习笔记】详解换根法(换根DP)

一.换根DP的概念 1.换根DP是什么? 换根DP,又叫二次扫描,是树形DP的一种。 2.换根DP能解决什么问题? 换根DP能解决不指定根结点,并且根节点的变化会对一些值产生影响的问题。例如子结点深度和、点权和等。如果要 暴力…

java社区养老年人服务系统springboot+vue

为了帮助用户更好的了解和理解程序的开发流程与相关内容,本文将通过六个章节进行内容阐述。 第一章:描述了程序的开发背景,程序运用于现实生活的目的与意义,以及程序文档的结构安排信息; 第二章:描述了程序…

python Cloudflare 批量关闭IPv6兼容性脚本

Cloudflare免费版控制台不给关IPv6,需要使用API关闭,先从我的个人资料里面申请API令牌,再执行脚本 import requests import jsonheaders {X-Auth-Email:cloudflare登入账户, #输入登入账户的邮箱X-Auth-Key: Global API Key, #输入上图申请…

数据结构(C语言)代码实现(六)——单链表的实现

目录 参考、格式 头文件LinkList.h 一、将函数的小括号写成中括号 二、读取权限冲突 三、L->Last指针没有移动 四、函数指针的使用 头文件完整代码 测试函数(主函数)test.cpp 测试结果 参考、格式 数据结构课本2.3节(严蔚敏版&a…

嵌入式学习第三篇——51单片机

目录 1,嵌入式系统 1,嵌入式系统的定义 2,单片机的定义 2,51单片机 1,开发环境 2,开发板使用的基本思路 1,查看原理图,查看芯片手册 2,获得调用硬件的管…

博途PLC限幅器(SCL代码)

PLC限幅器详细介绍,可以参考下面文章: https://rxxw-control.blog.csdn.net/article/details/128701050https://rxxw-control.blog.csdn.net/article/details/128701050三菱PLC限幅器 https://rxxw-control.blog.csdn.net/article/details/135212965

自研人工智能小工具-小蜜蜂(国外ChatGpt的平替)

国内有非常多好用的人工智能工具,但均无法完全替代国外ChatGpt。 ChatGPT相较于其他国内工具的优势在于以下几点: 创新的语言生成能力:ChatGPT是由OpenAI开发的先进的自然语言生成模型,它采用了大规模的预训练和精细调整方法。因此…

初探unity中的ECS

ECS是一种软件架构模式,就像MVC一样。ECS最早在游戏《守望先锋》中提及到的相关链接。ECS具体是指实体(entity)、 组件(component)和系统(system): 实体:实体是一个ID&a…

27. 云原生流量治理之kubesphere灰度发布

云原生专栏大纲 文章目录 灰度发布介绍灰度发布策略KubeSphere中恢复发布策略蓝绿部署金丝雀发布流量镜像 灰度发布实战部署自制应用金丝雀发布创建金丝雀发布任务测试金丝雀发布情况 蓝绿部署创建蓝绿部署测试蓝绿部署情况 流量镜像创建流量进行任务测试流量镜像情况 灰度发布…

【iOS ARKit】3D 人体姿态估计

与基于屏幕空间的 2D人体姿态估计不同,3D人体姿态估计是尝试还原人体在三维世界中的形状与姿态,包括深度信息。绝大多数的现有3D人体姿态估计方法依赖2D人体姿态估计,通过获取 2D人体姿态后再构建神经网络算法,实现从 2D 到 3D人体…

APK签名 v1、 v2、v3、v3.1、v4 解析

在 Android 应用签名中,V1 V2 V3 V4签名是不同的签名方案,具体描述如下: V1 签名(JAR 签名):早期 Android 应用签名的基本形式,基于 Java 签名(JAR 签名)规范。它将应用…

<Linux> 进程信号

目录 一、信号概念 二、信号的作用 三、信号的特性 四、信号捕捉初识 五、信号产生 (一)通过终端按键产生信号 (二)硬件中断 (三)系统调用产生信号 1. kill 函数 2. raise 函数 3. abort 函数 …