MeMOT是CVPR2022的文章, 最大的亮点是存储目标的之前所有帧的信息, 然后把之前所有帧的信息作为跟踪的线索进行编码, 从而实现同时检测与跟踪.
这种方式看似比较暴力, 而且网络的三部分组成都是Transformer结构(但同样也是CNN提取特征). 然而结合之前所有帧信息的思想(也许是想从batch方式借鉴一些, 助力online方式)还是值得思考的.
论文地址: 论文
目前没开源。
还是按文章顺序阅读.
- Introduction
作者在引言里批评了近期关于Transformer的MOT工作,包括TrackFormer, MOTR等. 他说这些方法把检测跟踪弄在了一起(query-key机制, 查询向量代表已有轨迹与新检测的特征), 但是这种组合 导致关联模块在对目标的实时变化进行建模时出现不必要的简化.
这句话的意思是, TrackFormer等方法对目标的实时变化很难在关联模块中体现(只用当前帧的特征), 实际上是为了强调后文用所有时间的特征的重要性.
为了解决这个问题,MeMOT就提出了长效的时空记忆机制,存储被跟踪目标过去所有帧的特征。MeMOT由三部分组成:
- 假设产生模块(Hypothesis Generation Module)
用以特征提取,得到当前帧目标可能的位置区域建议。可见主要是检测功能。用(Deformable)DETR实现。 - 记忆编码模块(Memory Encoding Module)
用以把每个跟踪目标给编码成一个向量,把这个向量叫做tracking embedding。 -
记忆解码模块(Memory Decoding Module)
顾名思义,是最后一个阶段,以假设产生模块的区域建议和记忆编码模块的轨迹特征(tracking embedding)为输入,联合进行匹配。 -
Related Work
在Related Work的最后一部分作者说了也许是灵感的来源,在NLP的时序推理任务,例如对话系统等,就有类似这种memory的工作。动作识别和视频实例分割的任务中也有用额外的memory去存储时序的特征。在近期一些单目标跟踪的算法中也用了memory,然而还没有人将memory用到MOT中去。
下面讲讲每一部分具体是怎么做的。
- Multi-Object Tracking with Memory
3.1 假设产生 Hypothesis Generation
假设产生模块很简单, 用DETR或Deformable DETR即可. (Deformable) DETR利用CNN提取图像特征, 将其线性映射为二维向量组后输入至Transformer编码器. 在解码器端, 输入的是代表目标的查询向量, 解码器层中与编码器层输出进行交叉注意力计算, 最终输出一堆向量, 每个向量代表了目标特征. 随后对每个向量(目标)的边界框和类别进行预测.
MeMOT将(Deformable) DETR的输出 先视作区域建议(region proposals), 记为Q p r o t ∈ R N p r o t × d \textbf{Q}{pro}^t\in \mathbb{R}^{N{pro}^t \times d}Q p r o t ∈R N p r o t ×d, 其中"pro"代表proposal, t t t代表第t帧, N p r o t N_{pro}^t N p r o t 代表proposal的个数. d d d是特征维数.
这里与Trackor有异曲同工之妙. Trackor利用Faster RCNN可自动学习区域建议的特性, 直接将当前帧的区域建议视为当前帧目标的预测, 和过去的轨迹进行匹配. 所以论文叫"Tracking without bells and whistles", 意为可以利用纯检测器进行跟踪.
MeMOT借鉴它的做法, 把Deformable DETR的输出当做建议了.
3.2 时空存储器 Spatial-Temporal Memory
前文一直在说有个东西要存储轨迹的所有帧特征. 其实不是所有帧, 因为太久远也没有意义, 因此保存部分帧数的特征就可以了. 作者定义了一个FIFO(先入先出)的结构来存储, 记为X ∈ R N × T × d \textbf{X} \in \mathbb{R}^{N\times T \times d}X ∈R N ×T ×d, 其中N N N为充分大的多余整个视频目标个数的数, 例如N = 600 N=600 N =6 0 0, T T T为要存储的时间, 例如T = 24 T=24 T =2 4.
因此, X \textbf{X}X存储了每个目标在每一帧的特征.
3.3 记忆编码器 Memory Encoding
前文说记忆编码模块要把每个目标编码成向量. 怎么做呢? 现在我们有的东西是Spatial-Temporal Memory里的一堆目标的一堆特征, 怎么转换为每个目标对应一个特定的tracking embedding呢?
作者设计了三个注意力模块: 1) 短时block, 用来做相邻帧的注意力, 以平滑噪声; 2) 长时block, 关联很多帧的特征, 来进一步提取特征; 3) 混合(fusion)block, 用来把长短时block的输出混合, 并输出最终的track embedding. 以下分别说明.
1. 短时block
对每个轨迹:
(论文给我的感觉是对每个轨迹单独算)
短时block只关注该轨迹临近T s T_{s}T s 帧的特征. 具体地, 对当前帧的特征X t − 1 ∈ R d \textbf{X}^{t-1} \in \mathbb{R}^{d}X t −1 ∈R d和临近T s T_{s}T s 帧的特征X t − 1 − T s : t − 1 ∈ R T s × d \textbf{X}^{t-1-T_s:t-1} \in \mathbb{R}^{T_s \times d}X t −1 −T s :t −1 ∈R T s ×d, X t − 1 \textbf{X}^{t-1}X t −1作为Q Q Q, X t − 1 − T s : t − 1 \textbf{X}^{t-1-T_s:t-1}X t −1 −T s :t −1作为K , V K,V K ,V进行交叉注意力计算.
再计算出每个轨迹的注意力结果后, 将其aggregate起来, 作为短时block的输出, 称作Aggregated Short Term Token, 记作Q A S T t \textbf{Q}_{AST}^t Q A S T t .
Q A L T t \textbf{Q}_{ALT}^t Q A L T t 的维度尚不清楚, 论文里没有提示.
2. 长时block
和短时block计算的方式基本一样, 不过长时block拿更多帧的特征进行注意力计算, 假设关注的帧数为T l T_l T l , 保证T l > T s T_l>T_s T l >T s . 假设T l T_l T l 内该目标的特征为X t − 1 − T l : t − 1 ∈ R T l × d \textbf{X}^{t-1-T_l:t-1} \in \mathbb{R}^{T_l \times d}X t −1 −T l :t −1 ∈R T l ×d, 和短时block一样, X t − 1 − T l : t − 1 \textbf{X}^{t-1-T_l:t-1}X t −1 −T l :t −1也是作为交叉注意力的K , V K,V K ,V.
那么Q Q Q 是谁呢?
这里作者用了一个循环结构(类似LSTM和RNN), Q Q Q就是整个Memory Encoding的输出, 也即Track Embedding, 作者起了个新名, 叫做动态记忆聚合token(dynamic memory aggregation token, DMAT), 记作Q D M A T t − 1 = { q k t − 1 } ∣ k = 1 N ∈ R d × N \textbf{Q}{DMAT}^{t-1}={q{k}^{t-1}}|_{k=1}^{N}\in \mathbb{R}^{d\times N}Q D M A T t −1 ={q k t −1 }∣k =1 N ∈R d ×N, 其中N N N为轨迹个数.
因此长时block把X t − 1 − T l : t − 1 \textbf{X}^{t-1-T_l:t-1}X t −1 −T l :t −1作为K , V K,V K ,V, 把Q D M A T t − 1 \textbf{Q}{DMAT}^{t-1}Q D M A T t −1 作为Q Q Q, 计算交叉注意力. 同理, 输出也要把每个目标聚合, 记为Q A L T t \textbf{Q}{ALT}^t Q A L T t .
3. 融合模块
随后, 将短时block和长时block的输出Q A L T t \textbf{Q}{ALT}^t Q A L T t , Q A L T t \textbf{Q}{ALT}^t Q A L T t concat在一起, 计算自注意力. 输出的就是tracking embedding, 也就是Q D M A T t − 1 \textbf{Q}_{DMAT}^{t-1}Q D M A T t −1 , 也就是下一帧的长时block的Q Q Q矩阵.
编码器模块如下图所示.
消融实验中, 关于长时短时的T T T的选择影响如下图:
\space
; 3.4 记忆解码器 Memory Decoding
前面我们根据(Deformable) DETR得到了区域建议Q p r o t \textbf{Q}{pro}^t Q p r o t , 根据记忆编码器得到了tracking embedding, 记为Q t c k t \textbf{Q}{tck}^t Q t c k t .
实际上Q t c k t \textbf{Q}{tck}^t Q t c k t 和Q D M A T t \textbf{Q}{DMAT}^t Q D M A T t 应该是一个东西.
我们将[ Q p r o t , Q t c k t ] [\textbf{Q}{pro}^t, \textbf{Q}{tck}^t][Q p r o t ,Q t c k t ]作为解码器的Q Q Q, 把图像特征z t ∈ R d × H W z_t\in \mathbb{R}^{d\times HW}z t ∈R d ×H W作为解码器的K , V K,V K ,V, 进行交叉注意力计算. 假设解码器的输出为[ Q ^ p r o t , Q ^ t c k t ] [\hat{\textbf{Q}}{pro}^t, \hat{\textbf{Q}}{tck}^t][Q ^p r o t ,Q ^t c k t ]
记忆解码器的输出是什么呢? 不同于以往的一些方法, 它不仅输出对目标位置的估计和置信度, 而且输出对目标遮挡程度估计的一个概率.
文中把衡量遮挡程度的score称为 objectness score, 把置信度的score称为 uniqueness score, 第i个目标在第t帧的两种score分别以o i t , u i t o_i^t, u_i^t o i t ,u i t 表示.
文章定义了最终的置信度, 就是objectness score和uniqueness score的乘积:
s i t = o i t u i t s_i^t=o_i^t u_i^t s i t =o i t u i t
因此对解码器的输出的预测结果就是两种置信度加位置. 对于输入Q ^ p r o t \hat{\textbf{Q}}{pro}^t Q ^p r o t , 输出的置信度为S p r o t \textbf{S}{pro}^t S p r o t , 同理对于输入Q ^ t c k t \hat{\textbf{Q}}{tck}^t Q ^t c k t 输出的置信度为S t c k t \textbf{S}{tck}^t S t c k t . 对每个目标都预测bbox b i t ∈ R 4 \textbf{b}_i^t\in\mathbb{R}^{4}b i t ∈R 4.
和TrackFormer等算法一样,是对两部分输入对应的输出分别处理的.
那么关键问题是这样定义新置信度有什么用呢?
作者说了两点.
-
在推理阶段, 筛选跟踪检测的置信度就考虑s i t ≥ ϵ s_i^t\ge\epsilon s i t ≥ϵ.
-
真值置信度的分配. 对已有轨迹Q ^ t c k t \hat{\textbf{Q}}{tck}^t Q ^t c k t 分配objectness score, 然后对假设产生模块的建议Q ^ p r o t \hat{\textbf{Q}}{pro}^t Q ^p r o t 分配uniqueness score, 注意假设产生模块的输出不仅仅是新目标, 也有旧轨迹. 用二部图匹配把proposal和所有的输出向量匹配. 分配真值置信度的说明如下图:
3.5 损失函数
整体的损失函数与MOTR中的相似, 对每个track query的损失都计算, 并且求平均.
L t c k i , t L_{tck}^{i,t}L t c k i ,t 表示第i i i个目标在第t t t帧的跟踪损失, 定义为:
其中L o b j ′ L_{obj}'L o b j ′和L u n i ′ L_{uni}'L u n i ′是对objectness score和uniqueness score置信度的focal loss, bbox就是L1 loss, iou就是广义IoU损失.
同理L d e t j , t L_{det}^{j,t}L d e t j ,t 表示第j j j个目标在第t t t帧的跟踪损失, 定义为:
Note, 这个损失在计算时, 作者加了一个额外的线性解码层, 来对假设生成模块输出的proposals
投影成置信度和bbox(也就是相当于又单独算了个(Deformable)DETR的损失).
; 4. 评价
该方法的可取之处在于有意识地使用了过去很多帧的信息去算注意力, 相当于暴力地让模型融合很多帧的信息.
但是它用了太多的注意力结构, 在8块A100上训练的. 可见模型是过于复杂, 而且效果不如FairMOT一类.
疑惑之处是, 提出了两种score, 尤其是代表visible的score很有新意, 可是我没看懂除了在计算新一种的置信度和往loss里增加了一项之外, 它还起了哪些作用. 既然可以预测visible程度, 我觉得还是可以进一步研究用处, 比如对预测目标visible程度低的用低阈值匹配, 而对于visible程度高的用高阈值匹配. 这样相较于用全局低阈值匹配(例如ByteTrack), 可以减少FP.
Original: https://blog.csdn.net/wjpwjpwjp0831/article/details/124713941
Author: wjpwjpwjp0831
Title: [论文阅读笔记12]MeMOT: Multi-Object Tracking with Memory, 有记忆的MOT算法
相关阅读1
Title: 科大讯飞麦克风阵列AIUI开放平台基本操作初级
下列图片如果不清楚可以直接访问我好朋友的淘宝链接,从链接中的网盘资料进行拉取。
店铺链接:首页-智能语音开发者联盟-淘宝网
产品链接:https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-23672887245.16.312a7247EicLXJ&id=644546095164
回声消除效果展示
https://mp.csdn.net/mp_blog/creation/editor/124886687
AIUI交互展示效果
一、创建应用
登录 AIUI开放平台
创建一个应用。分类无所谓,根据项目点击就好。
创建完成后就到了这个界面,记录好APPID和APPKEY之后使用。
- 添加技能
添加AIUI平台上已经做好的技能。比如添加天气。
下图为添加成功。
- 开启兜底设置
下图为开启兜底设置和配置兜底选项,兜底开启之后就可以不管说什么都会有回答了。
- 开启语音合成
选择不同的发音人和语音音量
- 保存修改和模拟测试
保存修改后即可生效。
六、同步到开发板
同步到开发板只需一次操作,永久生效(除非更新固件,定制固件的客户不需要担心)。Adb操作的详细驱动安装以及adb命令解释于《科大讯飞麦克风阵列adb操作详解》中查看。
- 通过adb命令adb pull /oem/build/AIUI/cfg/aiui.cfg
- 把记录好APPID和APPKEY替换aiui.cfg中的appid和key。
- 修改后保存。使用adb push aiui.cfg /oem/build/AIUI/cfg/aiui.cfg
- 通过adb进入shell,输入adb shell
- 输入命令 sync
- 输入命令 reboot
- 等待重启之后即可生效。
对于云端操作技能操作保存后会有一定延时才会生效,一般最多在一两分钟。
- 探索技能工作室(初级)
技能工作室于下图位置。
我们先创建一个问答库,办公室怎么走。
创建一个主题,设置几个问题和答案,单击保存。
设置完成后到应用配置添加技能。
之后保存修改,开发板就会更新问答了。
Original: https://blog.csdn.net/weixin_39869925/article/details/118028623
Author: 昊天大魔王
Title: 科大讯飞麦克风阵列AIUI开放平台基本操作初级
相关阅读2
Title: 有点奇怪!访问目的网址,主机能容器却不行
摘要:看看一般网络问题都怎么定位的。
本次网络故障:主机可以访问目的网址,但是容器里却不行。问题有点奇怪,让我们跟着唐老师分析的脚步,看看一般网络问题都怎么定位的吧。
问题现象
首先,这个节点上面的Docker是全新安装的,系统Centos也是刚装的。部门小伙伴报障说,启动Docker后,容器里面无法访问网络;但是Host主机上访问则明明是好的。
报错:
第一条红线是容器里面,第2条红线是主机上。
图示如下:
具体使用场景为,容器中用apt-get连华为云的镜像源(http://mirrors.tools.huawei.com ;)来安装软件包。但是容器中报错:Temporary failure resolving 'mirrors.tools.huawei.com'。
但是主机连这个源站却是OK的。
大家想一下,可能什么原因?
IP Forward转发
上手开始定位,所以我登录环境,准备启动一个空白容器先试下。
可是一启动容器,马上看到这么一条告警:
可以看到,这个告警信息,正常的容器以前是没有的。所以很明显,这个问题必须先搞定。
查看:
事实也是这样,从主机看待容器,它(容器)就是另一台"电脑"。报文经过主机给到容器,相当于主机帮忙"转发"给容器。所以主机必须要有"报文转发能力"。 ps,不好理解的话,可以回看一下唐老师前面的课程《跟唐老师学习云网络 - 网络命名空间》篇。
所以,我们在主机上面开启 ip_forward 开关:
修改/etc/sysctl.conf ,在文件里增加一条net.ipv4.ip_forward = 1
然后sysctl -p /etc/sysctl.conf 生效。
改完后,再启动容器,该Warning就消失了。可是发现DNS还是无法解析,错误Temporary failure resolving 'mirrors.tools.huawei.com'仍然存在。
DNS中search字段
容器中不通,那咱们就抓包看看。于是我在如下位置(所有容器报文出去都要经过的地方),即docker0上面抓包:
然后容纳中
发现发出去的查询DNS的报文中,为什么要在我询问的域名后面加个尾巴?(下图红线)
还记得《跟唐老师学习云网络 - DNS电话簿》章节的知识不,/etc/resolv.conf配置文件中,有个高级参数search字段。它可以用来帮你查询域名的时候,往目标域名尾巴上添东西的(即补上后缀)的。这个在Kubernetes的Service微服务里面,有用到。
So,我们将 /etc/resolv.conf 文件中的 search 字段给注释掉,这个参数暂时没用。
ps,最终验证发现,这个search参数,并不是当前容器网络不通的原因。 不过注释掉这个参数,也是合理的,因为我们并不需要novalocal后缀。
DNS不通
继续分析,容器里面无法解析"mirrors.tools.huawei.com"这个域名。那先看容器里面的/etc/resolv.conf文件,其内容:
可以看到是copy了主机Host里的/etc/resolv.conf文件。既然跟主机的DNS配置一样,那先看看主机怎么解这个域名。
在Host中使用:
发现,域名也是解不开的。。。囧,那主机上apt-get怎么获取到包的?咱们回顾一下《跟唐老师学习云网络 - DNS电话簿》章节的知识,解开一个域名,是单纯依靠DNS服务器的么?
So,赶紧看下 /etc/hosts 文件,发现一条写死的 IP记录。难怪。。。原来同事之前域名解不开就直接加了"偷懒"路径。(ps,容器也想加这种写死的域名-IP解析路径,可以使用docker run --add-host 参数。但是我不想只是规避,而是真的搞定网络问题)
于是找一台能解该域名的机器,把DNS服务器地址抄过来,放入 /etc/resolv.conf 配置文件见如下第一个DNS服务器记录。
然后把 /etc/hosts里面的记录删除,再试了下,主机可以解开域名了。
然后重新创建容器,并确认容器中的 /etc/resolv.conf 文件内容也对。
但是发现域名还是不通。。。
混杂模式
既然还是不通,那祭出大杀器Tcpdump呗(可以回看《跟唐老师学习云网络 - tcpdump》章节),所以继续在主机的docker0上开始抓包分析:
然后容器里面仍然执行:
但是好奇怪,这次又通了。(于是停掉tcpdump,跟同事说好了,结果他说还不行呀。我试下,确实又还不行)
试了几次发现,只要我tcpdump抓包,网络就通。一旦tcpdump停掉,网络就不通。大家想到了什么?
看过唐老师之前tcpdump章节的同学应该有印象,tcpdump命令,会使得网卡进入混杂模式,使它会接受不是属于自己的报文。
没错,通过
查询状态(右数第3位,0和1表示是否为混杂模式)。
结果为0x1003
而当开启tcpdump时为0x1103
那么说明问题就是docker0在默认情况下,并没有进入混杂模式导致的。
所以,修复方案就是把这个docker0的网卡,直接设置为混杂模式:
然后验证,一切OK。
再2次确认一下,将混杂模式关闭后,容器里面继续不通。
到此,整个网络问题搞定。
可能的根因
猜测可能这台机器是新安装的,一开始没有打开IP Forward转发开关。然后又是手动安装的Docker离线包,导致docker0为非混杂模式。
在打开IP Forward转发开关后,如果执行如下操作:
按理,应该也可以修复问题。
问题总结
本次容器网络不通问题,总结一下,大概:
本次网络故障,未涉及iptables相关问题,所以还算简单。感谢阅读。
Original: https://www.cnblogs.com/huaweiyun/p/16541729.html
Author: 华为云开发者联盟
Title: 有点奇怪!访问目的网址,主机能容器却不行
相关阅读3
Title: 哈工大 计算机网络 实验二 可靠数据传输协议(停等协议与GBN协议)
计算机网络实验代码与文件可见github:计算机网络实验整理
实验名称 可靠数据传输协议(停等协议与GBN协议)
实验目的:
本次实验的主要目的。
- 理解可靠数据传输的基本原理;掌握停等协议的工作原理;掌握基于 UDP 设计并实现一个停等协议的过程与技术。
-
理解滑动窗口协议的基本原理;掌握 GBN 的工作原理;掌握基于UDP 设计并实现一个 GBN 协议的过程与技术。
实验内容:
概述本次实验的主要内容,包含的实验项等。
1)基于 UDP 设计一个简单的停等协议,实现单向可靠数据传输(服务器到客户的数据传输)。 -
模拟引入数据包的丢失,验证所设计协议的有效性。
- 改进所设计的停等协议,支持双向数据传输;( 选作内容,加分项目,可以当堂完成或课下完成)
4)基于所设计的停等协议,实现一个 C/S 结构的文件传输应用。(选作内容,加分项目,可以当堂完成或课下完成) - 基于 UDP 设计一个简单的 GBN 协议,实现单向可靠数据传输(服务器到客户的数据传输)。
- 模拟引入数据包的丢失,验证所设计协议的有效性。
- 改进所设计的 GBN 协议,支持双向数据传输;(选作内容,加分项目,可以当堂完成或课下完成)
8)将所设计的 GBN 协议改进为 SR 协议。(选作内容,加分项目,可以当堂完成或课下完成)
实验过程:
以文字描述、实验结果截图等形式阐述实验过程,必要时可附相应的代码截图或以附件形式提交。
1.停等协议的设计与实现
1.1简单实现
停等协议是发送双方传输数据的一种协议方式。停等协议的接收、发送双方仅需设置一个帧的缓冲存储空间和帧序号只取0或1的两个状态标志位,便可有效地实现数据重发并确保接收方接受的数据不会重复。简单来说,停等协议就是发送方发送数据,等到接收方回复ack的时候才继续发送下一段数据。
1.2验证:
在实验过程中在数据发送过程中引入一个随机丢包以及随机丢失ack的情况,对于简单的停等协议来说,发生丢包或者丢失ack的情况下,也就是发送方并没有接收到接收方回复的ack的情况下,接收方当等待一定时间之后将会重传当前分组,直到接收到当前分组对应的ack的时候才会继续发送下一个分组。
1.3双向数据传输:
当实现双向数据传输的时候,主要的方式就是在客户端和服务器端都设置了接收和发送窗口,对于停等协议来说两种窗口的大小都设置为1,当客户端向服务器端发送数据的时候启用客户端的发送窗口和服务器端的接收窗口;当客户端从服务器端下载数据的时候启用客户端的接收窗口和服务器端的发送窗口。
1.4 C/S结构的文件传输应用:
对于C/S结构的文件传输来说,由于上一步实现了双向数据传输,因此在文件传输应用的时候实现的是可以提供客户端上传与下载数据的应用。在实现过程中根据客户端输入的命令决定是上传还是下载,同时将这一条命令发送给服务器端,在服务器端决定是否执行这个服务,如果服务端拒绝提供服务,那么本次连接中断;如果服务器端同意提供服务,以客户端上传文件为例讲述下述过程,客户端下载文件过程类似。当服务器端允许开始服务后,客户端进入传输数据状态,而服务器端进入接受数据状态。当数据传输结束之后客户端向服务器端发送特定报文内容标志传送任务结束,则本次客户端与服务器端的服务完成。
2.GBN协议的设计与实现
2.1GBN协议简单实现:
与简单停等协议相比,GBN协议事实上就是把发送窗口的长度设置为n,而接收窗口的长度仍保持为1,也就是GBN协议不接受乱序到达的数据,如果数据乱序到达,那么在接受处将会决定放弃这一部分数据;而GBN协议采用的是累积确认的方式,也就是说如果当前等待接收的数据编号为1,2,3,而收到了编号为3的ack,那么就表示这三个数据已经都正确接收了。GBN协议流程图如下所示:
图2.1 GBN流程图
2.2验证:
GBN验证方法和上述停等协议中基本一致,可见上述验证过程叙述。
2.3双向数据传输:
GBN双向数据传输方法和上述停等协议中基本一致,可见上述验证过程叙述。
2.4改进为SR协议:
为了解决GBN只能顺序接收数据的情况,在SR协议中,对于发送方来说:从上层收到数据后, SR发送方检查下一个可用于该帧的序号.如果序号位于发送窗口内,则发送该数据帧.否则要么将数据缓存,要么返回给上层之后再传输;同时当发送方接收到某个ACK的时候,将这个被确认的帧标记为已接收.如果该帧序号是窗口的下界,则窗口向前移动到最小序号的未被确认帧处.如果窗口移动了且有序号在窗口内的未发送帧,则发送这些帧。而对于超时事件来说,SR协议只重传超时的帧,并不重传所有超时帧之前的帧。
而对于SR接收方,只要是接收窗口内的帧都可以接收,SR接收方将确认一个正确接收的帧而不管其是否按序,失序的帧将被缓存,并返回给发送方一个该帧的确认帧,直到所有帧(序号更小的帧)都被收到为止,这时将一批帧顺序交付上层,然后向前移动滑动窗口。详细内容可见MOOC讲解截图如下:
图2.2 SR协议图
最终设计的基于SR协议的文件传输应用流程如下:
图2.3 文件传输应用流程图
实验结果:
采用演示截图、文字说明等方式,给出本次实验的实验结果。
1.GBN:
由于停等协议就是GBN协议中发送窗口长度设置为1,因此停等协议与GBN协议验证过程类似,统一演示如下:
获取服务器端时间:
图1.1 获取服务器端时间
模拟丢包:
图1.2 模拟丢包
在实现模拟丢包的过程中,设置的模拟丢包率和ack丢包率都是0.2,由上面的运行截图中可以看出,由于客户端发送的标号为2的ack报文丢失,因此在服务器端标号为2的数据发生超时之后要重传标号为2后面的所有数据,这样在一定的程度上就造成了资源的浪费,因此引入了SR协议。
2.SR文件传输:
在SR实现的文件传输服务中提供了客户端上传与下载文件的功能,演示结果如下:
图2.1 初始状态
图2.2 客户端申请上传文件
图2.3 客户端申请下载文件
问题讨论:
对实验过程中的思考问题进行讨论或回答。
- 由于UDP协议是无连接的传输协议,无法保证可靠的数据传输,因此如果在上层使用的时候需要上层来实现可靠的数据传输的部分。而且和TCP协议不同,UDP是一种无连接的协议,因此在传输数据之前并不需要三次挥手建立连接,尽管在本次实验中一部分代码确实使用了类似于连接的方式实现,但是需要注意的是那只是逻辑上的连接,并不存在真实的连接过程。
- SR协议的出现主要就是为了解决在使用GBN的过程中的一定量的资源浪费的情况,事实上SR协议、GBN协议、停等协议这三者在本质上的区别就是接收窗口和发送窗口大小的区别,至于其他的一些区别都是一些小的区别。
- 需要注意的是因为SR协议为每一个发送窗口的数据都设置了一个计时器,每次都重传超时的部分。在实际实现的过程中每次只需要比对发送窗口最低位是否超时,如果超时则重传,如果没有超时则表示发送窗口中没有超时的数据。
心得体会:
结合实验过程和结果给出实验的体会和收获。
通过本次实验对于基于UDP协议的可靠数据传输有了更加深刻的认识,掌握了停等协议,GBN协议以及SR协议,同时对于socket编程也有了更深入的了解。
Original: https://www.cnblogs.com/Zhengsh123/p/15860626.html
Author: zsh1234
Title: 哈工大 计算机网络 实验二 可靠数据传输协议(停等协议与GBN协议)