360网站seo怎么做/怎么优化网站关键词排名
一.基础概念
1.TCPSender在TCPSocket中的地位与作用
Lab0中实现了基于内存模拟的流控制-字节流(ByteStream),底层使用std::deque实现,根据最大容量Capacity进行容量控制。个人理解它相当于应用层的输入输出缓存区,用户依托Socket发送数据,读取数据。都要先将数据推入缓存区中,例如使用TCP发送数据,用户需要先将数据推入ByteStream中,TCPSender根据滑动窗口当前长度从ByteStream中读取一定数量的数据,之后再进行协议封装,最后推入发送队列中。TCPSender就是执行bytestream到Tcpsegment的工具。值得注意的是这个转换过程应该是自动执行的,且存在滑动窗口流量控制与超时重传机制。LAB4中将会实现TCPConnection他包括TCPSender与TCPReceiver。
从图中知道bytestream需要转换为TCPSegment需要添加协议头,添加序列号,SYN,payload以及FIN标志位。根据接收端接收到的ackno与window_size确定滑动窗口长度进行流量控制。故而要实现TCPSender时,可发送的数据范围由接收端给出的滑动窗口长度决定。协议头的标志位由当前TCPSender的状态决定。
2.何为端到端模型
Lab3原文如下:
TCP is a protocol that reliably conveys a pair of flow-controlled byte streams (one in each
direction) over unreliable datagrams. Two parties participate in the TCP connection, and
each party acts as both “sender” (of its own outgoing byte-stream) and “receiver” (of an
incoming byte-stream) at the same time. The two parties are called the “endpoints” of the
connection, or the “peers.
端到端是网络连接。 网络要通信,必须建立连接,不管有多远,中间有多少机器,都必须在两头(源和目的)间建立连接,一旦连接建立起来,就说已经是端到端连接了,即端到端是逻辑链路,这条路可能经过了很复杂的物理路线,但两端主机不管,只认为是有两端的连接,而且一旦通信完成,这个连接就释放了,物理线路可能又被别的应用用来建立连接了。简而言之,端到端的通信只要要处理好对应层内的协议就好了,且两端需要对等,协议需要具备普适性。一切优化更改都需要在其上一层进行,本层只负责本层的事务。我们要保证两个端点的行为一致性。
It’s important to remember that the receiver can be any implementation of a valid TCP receiver—it won’t necessarily be your own TCPReceiver. One of the valuable things about Internet standards is how they establish a common language between endpoints that may otherwise act very differently.
3.TCP协议头格式
TCPSender负责组装的TCPSegment格式见上图,发送端主要关注其中蓝色部分即可。序列号,FIN以及SYN标志与载荷数据。相对应的接收端需要关注红色部分。
3.ARQ
The basic principle is to send whatever the receiver will allow us to send (filling the window), and keep retransmitting until the receiver acknowledges each segment. This is called “automatic repeat request” (ARQ). The sender divides the byte stream up into segments and sends them, as much as the receiver’s window allows.
4.TCP如何知道消失丢失(超时重传机制)
TCPSender在发送消失时,会对已经发送的Segment进行一个缓存备份,我得TCPSender实现中使用了一个FIFO队列进行管理。只有当确认号大于缓存区中Segment的序列号时才进行出队操作。总而言之,我们追踪了滑动窗口发送的每一个Segment的序列号与其内容。通过确认号与序列号以及超时时间RTO来判断数据是否丢失。是否选择重传。
LAB3原文:
需要注意的是如果超时事件发生且窗口长度非0,需要将RTO时间加倍,这是因为在窗长非0时,出现了数据丢失那么当前网络拥塞较为严重,为了避免快速重传导致网络负载加倍,可以降低重传速率。
超时重传定时器的状态在RFC官方文档中有详细说明如下所示:
这里面有几个坑:
1.重传计时器在窗口发送时如果没有启动则会重新启动。这里注意并不是每发送一个数据包就启动一次定时器,对每一个数据包进行计时开销是极其大的。启动定时器是为了对存入重传缓冲区的数据进行计时,如果重传缓冲区空了就要关闭计时器,发送时将数据压入缓冲区,这时如果定时器未启动则启动定时器。
2.当收到新的ACK序号(必须大于之前的ACK序号),会进行定时器更新,具体为清除重传计数,恢复RTO时间。清除缓存区已经确认的数据。
3.如果重传事件发生且窗长大于0,那么必须使RTO加倍。
总结一下定时器有三种状态,分别为启动、停止、超时。只有在新数据推入且定时器未开启的时候会启动定时器,只有在重传缓冲区没有数据时会关闭定时器,超时发生时如果窗长大于0那么RTO必须加倍。立即定时器的三个状态时Lab3最重要的一点。
二.具体实现
1.TCP发送状态转移
要完成Lab3需要很好的理解下图,理解了发送的状态转移有助于在写发送窗口时,理清楚条件设置,如下所示:
CLOSED:此时未发送SYN同步标志,如果在这个状态那么发送SYN
SYN_SENT:此时已经发送SYN但是没有收到ACK这时要做的就是等待
SYN_ACKED1:此时收到ACK可以正常收发数据,根据窗口大小划分数据包,尽可能向发送队列写入数据
SYN_ACKED2:此时发送stream已经到达EOF但是FIN还未发送,需要发送FIN
发送了FIN后,窗口将不在发送新数据,此时应该保证fill_window()函数不做任何事情。具体代码实现如下:
void TCPSender::fill_window()
{// CLOSED (waiting for stream to begin no SYN sent)if (next_seqno_absolute() == 0){// send SYN_send_segment("", true);return;}// SYN_SEND (stream started but nothing acknowledged)else if (next_seqno_absolute() > 0&& next_seqno_absolute() == bytes_in_flight()){return;}size_t cur_window_size = (_window_size == 0) ? 1 : _window_size;while (cur_window_size > bytes_in_flight()){// SYN_ACKED (stream ongoing)if (next_seqno_absolute() > bytes_in_flight() && !stream_in().eof()){// flag for send successbool success_send = false;size_t payload_size = min(TCPConfig::MAX_PAYLOAD_SIZE,cur_window_size - bytes_in_flight());string payload = move(_stream.read(payload_size));// stream reached EOF and remaining window size can insert FIN flagif (stream_in().eof()&& cur_window_size - bytes_in_flight() - payload.size() > 0)success_send = _send_segment(move(payload), false, true);elsesuccess_send = _send_segment(move(payload));// Nothing to send cause segment length is zore,break.if (!success_send) break;}else if (stream_in().eof()){// SYN_ACK (stream ongoing, stream has reached EOF, but FIN flag hasn't been sent yet)if (next_seqno_absolute() < stream_in().bytes_written() + 2){_send_segment("", false, true);}else// FIN_SENTbreak;}}
}
2.ack接收部分
最难的发送部分实现完毕这个较为简单
//! \param ackno The remote receiver's ackno (acknowledgment number)
//! \param window_size The remote receiver's advertised window size
void TCPSender::ack_received(const WrappingInt32 ackno, const uint16_t window_size)
{// update window size_window_size = window_size;// get 64-bit absolute acknouint64_t abs_ackno = unwrap(ackno, _isn, _last_ackno);// if something impossible returnif (abs_ackno > next_seqno_absolute()) return;// if ackno is new ack, check retrans bufferif (abs_ackno > _last_ackno){// update new 64-bit ackno_last_ackno = abs_ackno;while (!_flight_buffer.empty()){const TCPSegment &seg = _flight_buffer.front();if (seg.header().seqno.raw_value() + seg.length_in_sequence_space()<= ackno.raw_value())_flight_buffer.pop();elsebreak;}// update timer setting_consecutive_retransmissions_count = 0;_rto = _initial_retransmission_timeout;if (!_flight_buffer.empty())_timer.start(_rto);else_timer.stop();}fill_window();
}
3.重传部分
//! \param[in] ms_since_last_tick the number of milliseconds since the last call to this method
void TCPSender::tick(const size_t ms_since_last_tick)
{// timer elapse_timer.tick(ms_since_last_tick);// if timer out and retrans buffer is not emptyif (_timer.is_expired() && !_flight_buffer.empty()){// retrans_segments_out.push(_flight_buffer.front());// window size has odd cause of internet's bad status, double RTOif (_window_size > 0){_rto *= 2;++_consecutive_retransmissions_count;//std::cout << _consecutive_retransmissions_count << std::endl;}_timer.start(_rto);}else if (_flight_buffer.empty()){_timer.stop();}
}
个人复盘请勿传播,引用。
相关文章:

CS144 Lab3 TCPSender复盘
一.基础概念 1.TCPSender在TCPSocket中的地位与作用 Lab0中实现了基于内存模拟的流控制-字节流(ByteStream),底层使用std::deque实现,根据最大容量Capacity进行容量控制。个人理解它相当于应用层的输入输出缓存区,用户…...

建筑可视化中使用云渲染的几大理由
在建筑行业中,可视化技术已成为不可或缺的一部分。无论是设计方案的展示、施工进度的模拟,还是最终效果的呈现,建筑可视化都发挥着至关重要的作用。 建筑可视化是指通过计算机技术和图形学算法,将建筑设计、规划和施工过程中的数据…...

Python数据可视化-地图可视化
1.首先绘制实现数据可视化的思维导图 具体要实现什么功能-怎么处理,先把思路写好 数据来源: 爬取的数据 运行结果: 部分代码: 完整代码请在下方↓↓↓👇获取 转载请注明出处!...

leetcode 动态规划(基础版)单词拆分
题目: 题解: 一种可行的dp做法是基于完全背包问题,将s看成是一个背包,wordDict看作是物品,然后往s中放入物品判断最终是否可以变为给定的s即可。这道题和上一题都用到了在dp如何枚举连续子串和状态表示:枚…...

Ubuntu/Linux调试安装南京来可CAN卡
准备好USB rules文件和can driver文件备用! 必做:放置USB rules文件到对应位置处理权限问题 而后:安装内核driver并编译。需求众多依赖编译环境,视情况安装填补。如GCC,G,make等等 进入对应64bit文件夹中,添加权限,执…...

vue2+TS获取到数据后自动叫号写法
1.父组件写法 初始化: //引入子组件 <odialog ref"odialogRef" onSure"onSurea"></odialog> //子传父private onSurea() {// 初始化信息/重新叫号来的数据this.initTabelData()setTimeout(() > {// 播放声音的数据this.search…...

28、架构-边界:微服务的粒度
微服务的粒度 在设计微服务架构时,确定微服务的粒度是一个关键问题。粒度过大或过小都会带来不同的问题,因此需要找到合理的粒度来划分微服务。下面详细探讨微服务粒度的合理范围及其影响因素。 1. 微服务粒度的上下界 微服务的粒度不应该只有唯一正确…...

开源API网关-ApacheShenYu首次按照启动遇到的问题
一.背景 公司有API网关产品需求,希望有图形化的后台管理功能。看到了ApacheShenYu,作为Apache的顶级项目,直接认可了。首先,感谢各位大神的付出,初步看这个项目是国内大厂中的大神创立的,在此表示膜拜&…...

uniapp获取证书秘钥、Android App备案获取公钥、签名MD5值
一、 uniapp获取证书秘钥 打开uniapp开发者中心下载证书打开cmd输入以下这段代码,下载提供查看到的密钥证书密码就可以了!下载证书在 java 环境下运行才可以 // your_alias 换成 证书详情中的别名,your_keystore.keystore 改成自己的证书文件…...

QT 如何储存多种数据类型(QVariant )
QVariant 是 Qt 框架中用于存储各种数据类型的类。它提供了一个强大的类型系统,允许你在运行时存储和检索多种类型的数据,而不需要在编译时确定类型。QVariant 的主要优点在于它的灵活性和通用性,这使得它在 Qt 的很多组件和机制中都被广泛使…...

持续总结中!2024年面试必问的操作系统面试题(九)
上一篇地址:持续总结中!2024年面试必问的操作系统面试题(八)-CSDN博客 十七、解释什么是操作系统的安全性和它的重要性。 操作系统的安全性(Operating System Security)是指操作系统采取的一系列措施来保…...

操作系统入门 -- 文件管理
操作系统入门 – 文件管理 1.文件管理概述 1.1 文件系统基本功能 目前,计算机内存的容量依然有限,并且其特性决定了数据无法长时间保存,因此把执行的数据以文件形式保存在外存中,等到需要使用时再调入内存。所以,操…...

由浅入深,走进深度学习(2)
今天分享的学习内容主要就是神经网络里面的知识啦,用到的框架就是torch 在这里我也是对自己做一个学习记录,如果不符合大家的口味,大家划走就可以啦 可能没有什么文字或者原理上的讲解,基本上都是代码,但是我还是想说…...

【Python Tips】创建自己的函数包并安装进Anaconda,像引入标准包一样直接import导入
目录 一、引言 二、方法步骤 步骤一:创建包目录结构 步骤二:配置__init__.py文件 步骤三:文件夹外配置setup.py文件 步骤四:终端Pip安装 三、结尾 一、引言 在编写项目代码的时候,有些自定义功能的函数是可以复用的。…...

【Python机器学习实战】 | 基于支持向量机(Support Vector Machine, SVM)进行分类和回归任务分析
🎩 欢迎来到技术探索的奇幻世界👨💻 📜 个人主页:一伦明悦-CSDN博客 ✍🏻 作者简介: C软件开发、Python机器学习爱好者 🗣️ 互动与支持:💬评论 &…...

备份和还原
stai和dnta snat:源地址转换 内网---外网 内网ip转换成可以访问外网的ip 内网的多个主机可以使用一个有效的公网ip地址访问外部网络 DNAT:目的地址转发 外部用户,可以通过一个公网地址访问服务内部的私网服务。 私网的ip和公网ip做一个…...

Java数组的初始化方法
Java数组的初始化方法 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!在Java编程中,数组是一种非常基础也非常重要的数据结构,它能够存储…...

通过分离有色和无色pdf页面减少打印费
前言 该工具是我认识的一位中科大的大佬在本科毕业的时候做的一个小工具,去打印店打印全彩的毕业论文的话会比较贵,他想到有没有一种方案可以实现有彩色页面的pdf和没有彩色页面的pdf分开打印,前者打印彩色,后者打印黑白…...

c语言--指针
前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文整理c语言中指针的相关知识点。 指针概念 指针存储的就是数据的地址。 直观理解: 李华家是北洋路130号1单元101 用变量处理数据: 我们去李华家拿数据。 用指针处理数据: 我们去北洋路130号1单元101拿数据…...

python-九九乘法表(对齐式1)
[题目描述] 输出九九乘法表,输出格式见样例。输入格式: 无输出格式: 输出乘法表,对齐方式见样例输出。样例输入 无样例输出 来源/分类(难度系数:一星) 完整代码展示: #对齐式1 a[] …...

thinkphp单独为某个接口设置缓存
参考 官方文档 $this->request->cache(__URL__,600);只需要在接口方法的开头添加这个代码即可...

OpenCV视觉--视频人脸微笑检测(超详细,附带检测资源)
目录 概述 具体实现 1.加载分类器 2.打开摄像头并识别人脸 3.处理人脸并检测是否微笑 效果 总结 概述 OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,广泛应用于图像处理和视频分析等领…...

docker 搭建 AI大数据模型 --- 使用GPU
docker 搭建 AI大数据模型 — 使用GPU方式 搭建本地大模型,最简单的方法!效果直逼GPT 服务器GPU系统HP580 G8P40Rocky9.2 安装程序AnythingLLM前端界面Open WebUIChatOllamaollama 一、AnythingLLM 介绍 AnythingLLM 是 Mintplex Labs Inc. 开发的一…...

面向对象, 常用类, 集合, 异常, JDBC, mysql数据库 复习
1.面向对象 (1)面向过程和面向对象 ● 面向过程的程序设计思想 (procedure -Oriented Programming),简称POP ● 关注的焦点是过程:过程就是操作数据的步骤。如果某个过程的实现代码重复出 现,那么就可…...

js取数组最大值之Math.max、Math.max.apply
js取数组最大值之Math.max、Math.max.apply Math.maxMath.max.applyapply()第一个参数为什么可以是null 最小值同理 Math.max Math.max(n1,n2,n3,…,nX) 支持传递多个参数,带有较大的值的那个数 Math.max(2,5,3,6,2,4,2,15,9,6,0,1)Math.max.apply apply() 语法&a…...

各种中间件的安装
文章目录 20232306mysql的wondows安装 2023 2306 mysql的wondows安装 常用mysql教程 springboot整合druid连接池SpringBoot配置Druid连接池 mysql的wondows安装 MySQL学习笔记 01、MySQL安装 这个是安装的具体思路 win10 安装 mysql 5.7 msi版的教程图文详解 这个是安装的…...

【Mysql】多表查询、隐式内链接、显式内连接、左外连接、右外连接
多表查询 什么是多表查询 •DQL: 查询多张表,获取到需要的数据 •比如 我们要查询家电分类下 都有哪些商品,那么我们就需要查询分类与商品这两张表 数据准备 创建db3_2 数据库 -- 创建 db3_2 数据库,指定编码 CREATE DATABASE db3_2 CHARACTER SET utf8;创建分类表与商品表 …...

Linux驱动开发(三)--新字符设备驱动开发 LED驱动开发升级
1、新字符设备驱动原理 使用 register_chrdev 函数注册字符设备的时候只需要给定一个主设备号即可,但是这样会 带来两个问题 需要我们事先确定好哪些主设备号没有使用 会将一个主设备号下的所有次设备号都使用掉,比如现在设置 LED 这个主设备号为200&…...

MCU的最佳存储方案CS创世 SD NAND
大家都知道MCU是一种"麻雀"虽小,却"五脏俱全"的主控。它的应用领域非常广泛,小到手机手表,大到航空航天的设备上都会用到MCU.市面上目前几个主流厂商有意法半导体(其中最经典的一款就是STM32系列)…...

40岁学习java是否需要报班学习?
在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「java的资料从专业入门到高级教程」, 点个关注在评论区回复“666”之后私信回复“666”,全部无偿共享给大家!!!应该不需要。各种公开免费的…...