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

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小时&#…...

磨金石教育摄影技能干货分享|高邮湖上观花海

江苏高邮,说到这里所有人能想到的,就是那烟波浩渺的高邮湖。高邮在旅游方面并不出名,但是这里的自然人文景观绝对不输于其他地方。高邮不止有浩瀚的湖泊,春天的油菜花海同样壮观。春日的午后,与家人相约游玩&#xff0…...

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&#xff0…...

[网鼎杯 2020 朱雀组]Think Java

SqlDict.java ,其中sql语句处存在sql注入漏洞 package .sqldict;import cn.abc.core.sqldict.Row; import cn.abc.core.sqldict.Table; import java...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...

DBLP数据库是什么?

DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC&#xf…...

高效的后台管理系统——可进行二次开发

随着互联网技术的迅猛发展,企业的数字化管理变得愈加重要。后台管理系统作为数据存储与业务管理的核心,成为了现代企业不可或缺的一部分。今天我们要介绍的是一款名为 若依后台管理框架 的系统,它不仅支持跨平台应用,还能提供丰富…...

【Ftrace 专栏】Ftrace 参考博文

ftrace、perf、bcc、bpftrace、ply、simple_perf的使用Ftrace 基本用法Linux 利用 ftrace 分析内核调用如何利用ftrace精确跟踪特定进程调度信息使用 ftrace 进行追踪延迟Linux-培训笔记-ftracehttps://www.kernel.org/doc/html/v4.18/trace/events.htmlhttps://blog.csdn.net/…...

python读取SQLite表个并生成pdf文件

代码用于创建含50列的SQLite数据库并插入500行随机浮点数据,随后读取数据,通过ReportLab生成横向PDF表格,包含格式化(两位小数)及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...