TCP相关概念
目录
一.滑动窗口
1.1概念
1.2滑动窗口存在的意义
1.3 滑动窗口的大小变化
1.4丢包问题
二.拥塞控制
三.延迟应答
四.捎带应答
五.面向字节流
六.粘包问题
七.TIME_WAIT状态
八.listen第2个参数
九.TCP总结
一.滑动窗口
1.1概念
概念:双方在进行通信时,一方可以一次性向另一方发送多条消息,这样可以将等待多个响应的时间重叠起来,进而提高数据通信的效率。
窗口大小指的是无需等待确认应答而可以继续发送数据的最大值,操作系统内核为了维护这个滑动窗口, 还需要开辟发送缓冲区 ,只有确认应答过的数据, 才能从缓冲区删掉。
其实可以将发送缓冲区当中的数据分为三部分:
- 已经发送并且已经收到ACK的数据。
- 已经发送还但没有收到ACK的数据。
- 还没有发送的数据。
1.2滑动窗口存在的意义
可以提高传输数据的效率
滑动窗口的大小等于对方窗口大小与自身拥塞窗口大小的较小值,因为发送数据时不仅要考虑对方的接收能力,还要考虑当前网络的状况。可以一次性发送多条消息,将多个等待时间重叠起来,滑动窗口越大,则网络的吞吐率越高,同时也说明对方的接收能力很强。
1.3 滑动窗口的大小变化
滑动窗口不一定会整体右移,会根据对方的接受能力不断改变。一般情况下滑动窗口是向右移动,说明对方接受能力稳定。如果对方不接收或16位窗口大小变小了,说明对方接受能力变小,滑动窗口会变小,即:start_index 会向右走,end_index不动;如果对方返回的16位窗口大小变大了,说明对方接受能力变大,滑动窗口会变大,即:start_index不动 ,end_index向右走。
1.4丢包问题
如果一次性发送多条数据,出现丢包了,该如何解决呢?
情况一:数据被对方接受了,但自己未收到对方ACK应答
这种情况相对好点,即使前面几条ACK应答丢了,但只要自己收到了较大的ACK应答(确认序号更大),就说明在收到的较大ACK应答对应的那条数据以及之前的数据,对方都接受到了。
情况二:数据未被对方接受到。那么直接进行重新发送。
在上面的那个例子中如果发送端主机连续三次收到了同样一个 "1001" 这样的应答, 就会将对应的数据 1001 - 2000 重新发送;
这个时候接主机B收端收到了 1001 之后, 再次返回的ACK就是7001了,因为之前的数据都已经收到了, 被放到了接收端操作系统内核的接收缓冲区中,这种机制被称为 "高速重发控制"(也叫 "快重传").
二.拥塞控制
如果双方在进行通信过程中,发生了大量的丢包问题,那么可能就是网络出现了问题。
如何去解决呢?
能否用滑动窗口解决:因为网络上有很多的计算机, 可能当前的网络状态就已经比较拥堵. 在不清楚当前网络状态下, 贸然发送大量的数据,是很有可能会进一步导致问题更严重。能否进行重传:一样,再次向网络上输入数据,就可能造成更严重的问题。
解决方法:
TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据, 此处引入一个概念程为拥塞窗口,定义:在拥塞窗口发送数据量以内不会拥塞,超过可能会引发拥塞问题。
例如,当出现拥塞时,将拥塞窗口定义为一个较小的值,当能收到ACK应答时,在不断去增大这个拥塞窗口(以指数级别)。滑动窗口的大小= min(对方的窗口大小,拥塞窗口)
补充:
在慢启动时是以指数级别增加的,增加到一定程度时,会线性增长。
此处引入一个叫做慢启动的阈值,当拥塞窗口超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长。当TCP刚开始启动的时候,慢启动阈值设置为对方窗口大小的最大值。在每次超时重发的时候,慢启动阈值会变成当前拥塞窗口的一半,同时拥塞窗口的值被重新置为1,如此循环下去。
三.延迟应答
当接受数据的一方收到数据后,不要立即进行ACK应答。(实际接收端处理数据的速度很快,可能在很短额时间内就将接受缓冲区内的数据读取了)接收端稍微等一会再进行ACK应答,比如等待200ms再应答,那么这时返回的ACK应答中窗口大小就能更大。
此外,不是所有的数据包都可以延迟应答。
- 数量限制:每个N个包就应答一次。
- 时间限制:超过最大延迟时间就应答一次(这个时间不会导致误超时重传)。
延迟应答具体的数量和超时时间,依操作系统不同也有差异,一般N取2,超时时间取200ms。
四.捎带应答
概念:当一方要给另一方发送响应时,同时也要给对方发送消息,那么二者可以一起发送,双方通信时就不是单独发送确认报文,单独发送ACK响应,这样也增大了传输效率。
五.面向字节流
在创建一个TCP的socket时,同时在内核中会创建一个发送缓冲区和一个接收缓冲区。由于缓冲区的存在,发送数据的方式和数据的格式完全无关系,即TCP程序的读和写不需要匹配。
1.调用write时, 数据会先写入发送缓冲区中, 如果发送的字节数太长, 会被拆分成多个TCP的数据包发出。 如果发送的字节数太短, 就会先在缓冲区里等待, 等到缓冲区数据有一定数量了, 或者其他合适的时机发送出去。(调用write可以认为是在拷贝数据到相关内核中,具体什么时候发送是由操作系统决定的)
2.在接收数据的时候, 数据也是从网卡驱动程序到达内核的接收缓冲区,然后应用程序可以调用read从接收缓冲区拿数据;
TCP既有发送缓冲区, 也有接收缓冲区, 那么对于这一个连接, 既可以读数据, 也可以写数据. 这个概念叫做 全双工
例如:
写100个字节数据时,可以调用一次write写100字节,也可以调用100次write,每次写一个字节。
读100个字节数据时,也完全不需要考虑写的时候是怎么写的,既可以一次read100个字节,也可以一次read一个字节,重复100次。
六.粘包问题
这个概念是在应用层上的。因为TCP通信是面向字节流的,
在TCP的协议头中, 没有如同UDP一样的 "报文长度" 这样的字段, 但是有一个序号这样的字段。站在传输层的角度,TCP的报文是按照序号排好序放在缓冲区中,站在应用层的角度, 看到的只是一串连续的字节数据。
如何解决呢?
要解决粘包问题,本质就是要明确报文和报文之间的边界。
对于定长的包,保证每次都按固定大小读取即可。
对于变长的包,可以在报头的位置,约定一个包总长度的字段,从而就知道了包的结束位置。比如HTTP报头当中就包含Content-Length属性,表示正文的长度。
对于变长的包,还可以在包和包之间使用明确的分隔符。因为应用层协议是程序员自己来定的,只要保证分隔符不和正文冲突即可。
UDP协议来说, 是否也存在 "粘包问题" 呢?
不存在,因为UDP协议是面向数据报的。
面向数据报:当应用层交给UDP多长的报文,UDP就原样发送,既不会拆分,也不会合并,这就叫做面向数据报 ,不能够灵活的控制读写数据的次数和数量。
因为UDP报头当中的16位UDP长度记录的是UDP报文的长度,因此UDP在底层的时候就把报文和报文之间的边界明确了,而TCP存在粘包问题就是因为TCP是面向字节流的,TCP报文之间没有明确的边界。站在应用层的角度,使用UDP的时候,要么收到完整的UDP报文,要么不收,不会出现“半个”的情况。
七.TIME_WAIT状态
前面已经介绍了,双方在通信过程中,主动断开连接的一方,在完成4次挥手后,不会立即进入CLOSED状态,而是进入短暂的TIME_WAIT状态等待若干时间,最终才会进入CLOSED状态。
若是服务器先断开连接,在TIME_WAIT的时间里,该连接处于TIME_WAIT期间,如果服务器想要再次重新启动,就会出现绑定失败的问题(绑定同一个端口号)。因为在TIME_WAIT期间,这个连接并没有被完全释放,也就意味着服务器绑定的端口号仍然是被占用的,此时服务器想要继续绑定该端口号启动,就只能等待TIME_WAIT结束。
解决办法:setsockopt,让服务器在调用socket函数创建套接字后,继续调用setsockopt函数设置端口复用。
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
参数解释:
sockfd:需要设置的套接字对应的文件描述符。
level:被设置选项的层次。比如在套接字层设置选项对应就是SOL_SOCKET。
optname:需要设置的选项。该选项的可取值与设置的level参数有关。
optval:指向存放选项待设置的新值的指针。
optlen:待设置的新值的长度
例如:
int opt = 1;
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
八.listen第2个参数
创建TCP服务端流程:套接字创建、绑定、监听,调用accept函数。
TCP在进行连接管理时会用到两个连接队列:
- 全连接队列(accept队列)。全连接队列用于保存处于ESTABLISHED状态,但没有被上层调用accept取走的连接。
- 半连接队列。半连接队列用于保存处于SYN_SENT和SYN_RCVD状态的连接,也就是还未完成三次握手的连接。
一般全队列的长度是等于listen的第2个参数的值+1.
意义:服务器启动一般会启动多个线程(数量也是有限的),主线程从底层accept上来连接后就可以将其交给这些服务线程进行处理。当所有线程都在运行时,维护一个全队列,不会直接拒接客户端的连接请求,而是在一些线程空闲时在accept这些全队列中的请求。
九.TCP总结
可靠性:
- 检验和。
- 序列号。
- 确认应答。
- 超时重传。
- 连接管理。
- 流量控制。
- 拥塞控制。
提高性能:
- 滑动窗口。
- 快速重传。
- 延迟应答。
- 捎带应答。
TCP的各种机制实际都没有谈及数据真正的发送,这些都叫做传输数据的策略。TCP协议是在网络数据传输当中做决策的,它提供的是理论支持,比如TCP要求当发出的报文在一段时间内收不到ACK应答就应该进行超时重传,而数据真正的发送实际是由底层的IP和MAC帧完成的。
相关文章:

TCP相关概念
目录 一.滑动窗口 1.1概念 1.2滑动窗口存在的意义 1.3 滑动窗口的大小变化 1.4丢包问题 二.拥塞控制 三.延迟应答 四.捎带应答 五.面向字节流 六.粘包问题 七.TIME_WAIT状态 八.listen第2个参数 九.TCP总结 一.滑动窗口 1.1概念 概念:双方在进行通信时&a…...

MySQL锁篇
MySQL锁篇 一、一条update语句 我们的故事继续发展,我们还是使用t这个表: CREATE TABLE t (id INT PRIMARY KEY,c VARCHAR(100) ) EngineInnoDB CHARSETutf8;现在表里的数据就是这样的: mysql> SELECT * FROM t; —------- | id | c | —…...

SWF (Simple Workflow Service)简介
Amazon Simple Workflow Service (Amazon SWF) 提供了给应用程序异步、分布式处理的流程工具。 SWF可以用在媒体处理、网站应用程序后端、商业流程、数据分析和一系列定义好的任务上。 举个例子,下图表明了一个电商网站的工作流程,其中涉及了程序执行的…...

java(Class 常用方法 获取Class对象六种方式 动态和静态加载 类加载流程)
ClassClass常用方法获取Class对象六种方式哪些类型有Class对象动态和静态加载类加载流程加载阶段连接阶段连接阶段-验证连接阶段-准备连接阶段-解析初始化阶段获取类结构信息Class常用方法 第一步:创建一个实体类 public class Car {public String brand "宝…...

【数据结构】线性表和顺序表
Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 1.线性表 2.顺序表 2.1 静态顺序表 2.2 动态顺序表 2.3移除元素 1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线…...
Ubuntu数据库安装(mysql)
##1.下载mysql-apt-config_0.8.22-1_all.deb并且安装 wget https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb sudo dpkg -i mysql-apt-config_0.8.22-1_all.deb##2.更新apt-updata sudo apt update##3.如果出现如下图情况执行以下命令 [外链图片转存失败,源站可…...

MyBatis-Plus的入门学习
MyBatis-Plus入门学习简介特性快速开始MyBatis-Plus的注解详解Tableld主键生成策略1、数据库自动增长 AUTO2、UUID3、Redis生成id4、MP主键自动生成TableNameTableField自动填充测试方法:update乐观锁select查所有根据id查多个id批量查询简单条件查询(通…...
华为OD机试题 - 内存池(JavaScript)
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:内存池题目输入输出示例一输入输出说明Code解题思路版权说明华为…...

数据库索引原理
数据库索引的作用是做数据的快速检索,而快速检索实现的本质是数据结构。像二叉树、红黑树、AVL树、B树、B树、哈希等数据结构都可以实现索引,但其中B树效率最高。MySQL数据库索引使用的是B树。二叉树:二叉树中,左子树比根节点小&a…...

字符函数和字符串函数详解(1)
目录前言strlen函数strlensizeofstrcpy函数strcat函数strcmp函数总结前言 最近要调整状态,写的文章质量不佳让大家失望,我现在也在反思我在做什么,我会什么,我学了什么。等我想明白的那天,我一定能跟大家顶峰相见的&a…...

【数据分析:工具篇】NumPy(1)NumPy介绍
【数据分析:工具篇】NumPy(1)NumPy介绍NumPy介绍NumPy的特点数组的基本操作创建数组索引和切片数组运算NumPy介绍 NumPy(Numerical Python)是Python的一个开源的科学计算库,它主要用于处理大规模的多维数组…...

mysql时区问题
设置mysql容器时间与服务器时间一致 问题背景: 今天测试发现一个问题,时间不一致,当工单入库时,其创建时间和更新时间应该是一样的,即使不一样最多只会错几秒的时间;实际上两个时间相差的大概8小时&#…...

磨金石教育摄影技能干货分享|高邮湖上观花海
江苏高邮,说到这里所有人能想到的,就是那烟波浩渺的高邮湖。高邮在旅游方面并不出名,但是这里的自然人文景观绝对不输于其他地方。高邮不止有浩瀚的湖泊,春天的油菜花海同样壮观。春日的午后,与家人相约游玩࿰…...

mysql navicat忘记密码
mysql忘记密码是常用的事情,那么如何解决它呢?1、首先将MySQL的服务关闭,两种方法:(1)打开命令行cmd输入net stop mysql命令即可关闭MySQL服务。(2)打开任务管理器,找到服…...

Git的下载、安装、配置、使用、卸载
前言 我是跟着狂神老师学的。该博客仅用于笔记所用。 下面是老师的B站和笔记 B站:https://www.bilibili.com/video/BV1FE411P7B3?p1&vd_source9266cf72b1f398b63abe0aefe358d7d6 笔记:https://mp.weixin.qq.com/s/Bf7uVhGiu47uOELjmC5uXQ 一、准备工…...

【博客631】监控网卡与进程网络IO使用情况
监控进程的网络IO使用情况 1、vnstat 由于 vnstat 依赖于内核提供的信息,因此执行以下命令来验证内核是否提供了 vnStat 所期望的所有信息: # vnstat --testkernel This test will take about 60 seconds. Everything is ok.不带任何参数的 vnstat 将…...

【Leetcode】【简单】35. 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], target 5 输出: 2 示例 2: 输入:…...
sql面试题
mysql优化 优化准则: 建表时:合理选择字段的类型,单表字段数量 sql查询尽量单表操作,避免复杂操作,复杂的多表通过java代码实现 构建复合索引优化,索引尽量可以覆盖主要业务查询 sql避免索引失效 避免大…...

SQL 进阶刷题笔记
SQL 进阶刷题笔记 一、MySQL 进阶 这里主要是 MySQL 刷题相关笔记,方便后面温习和查阅,希望可以帮到大家!!! 题1 请计算每张SQL类别试卷发布后,当天5级以上的用户作答的人数uv和平均分avg_score࿰…...
[网鼎杯 2020 朱雀组]Think Java
SqlDict.java ,其中sql语句处存在sql注入漏洞 package .sqldict;import cn.abc.core.sqldict.Row; import cn.abc.core.sqldict.Table; import java...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...