收集的、待整理的文章
先不看架构了,直接看Aurora了
- wolfcs大佬的博客优先看,在reference那一节里面说了
- https://www.cnblogs.com/ukernel/p/8976984.html
- https://www.slidestalk.com/u42/t8efjk
- https://blog.csdn.net/ktlifeng/article/details/78533355
reference
sourceforge官网 【05年出的,更新到09年】
ppt 、poster、documention、discussion/help 版块(including Chinese)
udt初步介绍 里面有UDT的架构图,可惜没有再出后续了…
大佬系列博客:udt源码分析 后续想要读源码的话可以==再仔细看一下==(目前只是大概浏览了下),which我觉得讲得真的不错
大佬还有系列在oschina的平台上
- 发送窗口大小及发送速率的调整
- 实现分析总结
UDT::startup()的调用过程为:UDT::startup()-> CUDT::startup() -> CUDTUnited::startup()。
从这里也可以看出UDT、CUDT、CUDTUnited之间的关系
UDT的命名规则有些讲究,前缀代表着数据类型
设计架构
socket创建那一章说的:UDT的使用者在调用UDT API时,UDT API会直接调用CUDT类对应的static API函数,在CUDT类的这些static API函数中会将做实际事情的工作委托给s_UDTUnited的相应函数,但这个委托调用会被包在一个try-catch block中。s_UDTUnited的函数在遇到异常情况时抛出异常,CUDT类的static API函数捕获异常,根据捕获到的异常的具体类型,创建不同的CUDTException对象设置给s_UDTUnited的线程局部存储变量m_TLSError中并向UDT API调用者返回错误码,UDT API的调用者检测到错误码后,通过UDT::getlasterror()获取存储在m_TLSError中的异常。
bind( )函数那一章说的: 和socket创建时一样是==分为3层==:UDT命名空间中提供了给应用程序调用的接口,可称为UDT API或User API;User API调用CUDT API,这一层主要用来做错误处理,也就是捕获动作实际执行过程中抛出的异常并保存起来,然后给应用程序使用;CUDT API调用CUDTUnited中API的实现。
“此处可以看到,CUDT提供的这一层API,一个比较重要的作用大概就是做异常处理了。”
其实这里没有很懂UDT的==设计艺术==,为什么要分三个层次的类,中间那个特别像个中间件,为什么异常处理要单独拎出来。
bind( )函数那一章还介绍了UDT的多路复用器CMultiplexer、通道CChannel、发送队列CSndQueue和接收队列CRcvQueue的含义
CChannel
系统UDP socket的一个封装,它主要封装了系统UDP socket handle,IP版本号,socket地址的长度,发送缓冲区的大小及接收缓冲区的大小等信息,并提供了用于操作 系统UDP socket进行数据收发或属性设置等动作的函数。
其实没有很懂多路复用器(Multiplexer)和socket之间的关系 ( 监听端口到底是什么操作?我理解的目前是socketchannel可以实现在一个线程里面监听多个某个端口的状况 ( 是否接收了数据等等 ) 并将更新的情况跟selector ( 也就是多路复用器 ) 交流 ,which会选择让哪个socket去处理这件事情) 、
CRcvQueue
在接收队列CRcvQueue的worker线程中,接收到一条消息之后,它会根据消息的目标SocketID,及发送端的地址等信息,将消息以不同的方式进行dispatch
这个UDT源码剖析系列博客讲得很详细,相当于每个头文件在讲解了
这个博客相当于翻译了udt的论文
==CS 224==的那个project是怎么整的 还得看下
udt思路及代码分析
- 这个里面有代码架构分析
- 这个里面有伪代码
官方提供的reference里面就有api手册 [代码的doc文件里面也可以离线查看]
代码架构
1 | ./src: UDT source code |
整体结构
refer@WolfCS的UDT实现分析总结
UDT Socket是UDT中的核心,同时它也是一座桥梁,它将UDT的使用者应用程序与内部实现部分对于数据结构的管理、网络数据的传输连接起来。
应用程序通过它将数据放进发送缓冲待发送,或者借由它来获取从网络接收数据。而与网络进行交互的部分,则从它那里拿到要发送的数据进行发送,或者在收到packet时将packet dispatch给它。
数据接收部分框架

数据发送部分框架

UDT socket structures

socket文件描述符 + 错误码 + UDT socket集合 + TraceInfo ()
TraceInfo , performance的一些数据
aggregate values
- pktSndLossTotal 和 pktRcvLossTotal的区别??这个RcvLoss怎么测试呢==??==
local values since last recorded time
目前理解是一段时间的period算出来的值 ==??不是很确定==
instant values at the time they are observed
UDT socket functions
- perfmon
- 其他的大部i分都跟传统的socket编程的api一致
CC Base Class
ccc.h文件定义了父类
app/cc.h里面定义了一个基于CCC的拥塞控制方法,是一个good tutorial
注意事项
- 不要在CCC内部或者它的继承类中调用regular UDT API, 会有未知错误发生
- CCCFactory<…> 是一个C++模板,不需要用类去继承他
- UDT不会立马释放CCCFactory<…>的实例,应该在application类里面释放,只要是在setsockopt()后就可以
一些中途冒出来的想法
正如Sigcomm‘2020所示,我们的主机开销也算是延迟的一部分,那么我们的算法的耗时会不会影响整个delay的状况呢 ?
代码梳理
UDT部分
跟UDTv4相比,src/core内改动比较大的是
- api.cpp
- buffer.cpp
- core.cpp 改动相当大 ,不仅添加了一些属性,还添加了不少功能
ccc.cpp虽然改动大, 但是本身就是要被继承的,which means没关系
PCC
pcc_sender
主要是PccSender类,which
functions
触发型
- void OnCongestionEvent ( )
- void OnPacketSent ( )
调整型
- QuicBandwidth PacingRate ( )
- QuicTime ComputeMonitorDuration ( )
- QuicTime GetCurrentRttEstimate ( )
- -void UpdateCurrentRttEstimate( )
- -bool ShouldCreateNewMonitorInterval( )
- -QuicBandwidth UpdateSendingRate
总结
- 在事件(发包和ack (==目前不确定==这个CongestionEvent是不是ack获得的) )发生的时候采取一些操作(比如信息统计( RTT估计值 )、调整结构信息)
- 调整结构信息
- sending rate (pacing) 的计算和调整
- MI大小调整 以及 ==创建(??)==新的MI
- RTT
member
观测值
- avg_rtt_
- sending_rate_
工具
- utility_calculator_ (PccUtilityCalculator
- rate_controller_ ( PccRateController
- rate_control_lock_ (mutex
- interval_queue_ (PccMonitorIntervalQueue
- interval_analysis_group_ (PccMonitorIntervalAnalysisGroup、
rate-control
在这里面发现了好几个Options的参数
- pypath
- pyhelper ( default : pcc_rate_controller )
利用了Python3.5进行了混编
先尝试下能不能换成3.6
坑太多,试到一半放弃了,不然其实是可以的
不然就开始配环境(对…换了台g8就可以
代码疑惑
为什么可以不提前声明,也不include。虽然queue.h确实是在之前被编译的,但是这个就不需要指明依赖关系么
又用到工厂模式了,可惜我还是不会( 不过也不是重点,回头看下
之前master说TCP buffer不需要很大,不停poll就行?? why ?没有很理解
用sourceCode整理一下代码结构
from aurora test
sourceCodes 如何处理这么多宏定义的事情…. 一下子理清代码结构还是很重要的(lxg
C++特性
chrome的Base库对于[]的使用方法 –》 跨平台开发
zyh给的link,针对QUIC_EXPORT_PRIVATE,有空学一手
哪些需要mutex的lock,哪些不需要,比如说为啥RTT更新就不需要
pcc_sender.cpp里面
类的explicit到底有什么作用来着…还有=delete之类,还有GCC扩展之类
这种单独的匿名的namespace意义何在?在pcc_lin_ucalc.cpp
1
2
3
4
5
6namespace {
// Coefficeint of the loss rate term in utility function.
const float kLossCoefficient = 5.0f;
// Coefficient of RTT term in utility function.
const float kRttCoefficient = 1.0/30000.0f;
} // namespace后面的都不在这个namespace里面,所以是文件里面的可以看到,文件外面的看不到 ?
待整理
- 函数名的mangle过程这儿讲得特别好
1 | ByteComparator.obj : error LNK2019: unresolved external symbol "int __cdecl does_not_exist(void)" (?does_not_exist@@YAHXZ) referenced in function "void __cdecl TextScan(struct FileTextStats &,char const *,char const *,bool,bool,__int64)" (?TextScan@@YAXAAUFileTextStats@@PBD1_N2_J@Z) |
- 利用了Python.h进行了混编
- BBR的研究
- dog大佬关于BBR的问题剖析,我觉得挺好的,等当前这个demo做完,就看看这个,然后基于BBR改进
- 这个讲了BBR ProbeMore的两阶段探测,里面的idea我确实也没有很理解。