UDT内部代码分析
来源:互联网 发布:d3.js力导向拖拽 编辑:程序博客网 时间:2024/05/17 08:54
一. 报文发送
1.CSndQueue::worker中调用CChannel::sendto发送数据报文。
2.CSndQueue::sendto中调用CChannel::sendto发送其他报文, 种类较多主要有:
1)CUDT::connect中调用CSndQueue::sendto发送建立连接请求。
2) CUDT::sendCtrl中调用CSndQueue::sendto发送控制报文。
3) CUDT::listen对客户端过来的连接建立握手包给予应答,也是调用CSndQueue::sendto发送报文。
二. 报文接收
CRcvQueue::worker 是所有报文的接收函数,调用CChannel::recvfrom从网络上接收报文。
对收到的包分别处理:
1) Rendezvous类型的连接请求包和建立过程包都会调用 CRcvQueue::storePkt 缓存起来; UDT::connect 中有一个接收点,调用CRcvQueue::recvfrom从这个缓冲区里面取. 非Rendezvous类型的连接请求和建立过程包会交给m_pListener的CUDT::listen处理。
2) 根据目的socketID能查到已经建立好的连接,这样的包还分数据包和控制包两种,分别调用 CUDT::processData , CUDT::processCtrl加以处理.
三. 定时器控制
1. 定时器变量和数值
CTimer::rdtsc在Linux下返回的是微秒(即1/ 1000000秒); 而在windows下则返回一个高精度计数,s_ullCPUFrequency为每微妙高精度计数个数。
经换算,一些变量的默认值:
m_ullSYNInt : 10ms
m_ullACKInt: 10ms 含义应该是一旦收到数据包,那么最多10ms后就会发出ACK
m_iRTT: 初始网络RTT为100ms
m_iRTTVar: 初始RTT变幅为 50ms
m_ullNAKInt: m_iRTT+4×m_iRTTVar 因此初始值为300ms
m_ullMinEXPInt: 初始值为100ms
2. 定位器处理
定时器处理和接收处理共用线程CRcvQueue::worker。底层socket在linux下被设置成了非阻塞,windows下是设置了1ms接收超时, 因此接收处于不断查询中,每接收一次返回处理后就进入定时器处理,调用的是CUDT::checkTimers, 主要的处理:
1) 确认应答(ACK)
如果超过设定的下次应答时间,或者连续接收到的数据包数超过设定的应答间隔,发送应答包ACK, 发送之后更新下次应答时间,把连续接收数据包的计数清零。
如果通过CCC设置的应答时间间隔和应答个数间隔都非常大,流程看还会每m_iSelfClockInterval(64)个包发一次应答.
2) 定应答(NAK)
如果有丢包,并且超过设定的下否定应答时间,则发送NAK, 并且更新时间。
3) 到期(老化)处理
如果超过设定的下次到期时间
1)连续16次超时并且,总无应答时间超过10秒,则关闭连接。
2)将发出后没有收到应答的包序号填入丢失列表,并马上触发重发
3)如果没有包在发送,则发送keep-alive包
4)到期次数加1,最小到期间隔根据到期次数加大间隔(倍速增长),保证最小为100ms.
更新下次到期时间.
5) 相关流程
到期次数m_iEXPCount在收到数据或者控制包后都会重置为1,同时下次到期时间也会被更新。一旦长时间无应答,m_iEXPCount就会持续增加,直到连接老化。
四. 报文缓存buffer组织及窗口机制
CCC窗口参数m_dCWndSize对应的内部变量是CUDT. m_dCongestionWindow, 在CUDT::packData函数内,这个变量起到了流控的作用(同时另外一个起流控作用的参数是m_dPktSndPeriod,控制发包之间的间隔时间(因为windows下使用的定时器精确度在15ms左右,因此实际上导致如果发包间隔不为0,则发包间隔一定大于这个值,因此更合理的是按每秒发包个数来控制). UDTsocket设置UDT_SNDBUF参数则控制了发送缓冲区的大小,发送缓冲区不够时,如果设置了非同步方式,则失败返回;阻塞式连接情况下,如果设置了发送超时,则超时返回,否则一直阻塞。
而接收缓冲区一旦不够用时,UDT会把通道内的包接收起来直接丢弃,其影响相当于网络丢包。
五. UDT线程
总共三个线程, 执行函数分别是:
CSndQueue::worker : 发送处理
CRcvQueue::worker: 接收和定时器处理
CUDTUnited::garbageCollect: 垃圾(如残连接)清理
- UDT内部代码分析
- UDT 分析
- udt代码初探
- UDT 源码分析
- UDT协议详细分析
- UDT源码分析(2):UDT协议数据包格式分析
- UDT协议相关初始化分析
- UDT源码剖析(三):UDT::startup()过程代码注释
- UDT源码剖析(五):UDT::cleanup()过程代码注释
- UDT源码剖析(六):UDT::socket()过程代码注释
- UDT源码剖析(三):UDT::startup()过程代码注释
- UDT源码剖析(五):UDT::cleanup()过程代码注释
- UDT源码剖析(六):UDT::socket()过程代码注释
- UDT源码分析(1):UDT协议是什么?
- UDT协议实现分析——UDT初始化和销毁
- UDT协议实现分析——UDT Socket的创建
- UDT
- UDT分析及Android平台移植
- TestNG学习笔记(二)——HelloWorld
- 模拟实现 string类
- MarkDown编辑器的基本语法
- 自旋锁、阻塞锁、重入锁、偏向锁、轻量锁和重量锁
- 连续子数组的最大和
- UDT内部代码分析
- TestLink学习四:TestLink1.9.13使用说明
- Oracle数据库对于大对象二进制文件的存储及下载
- 线程死锁
- 50.远程连接服务器 SSH, XDMCP, VNC, XRDP
- 话说 依赖注入(DI) or 控制反转(IoC)
- Android中Png,jpeg格式的亚索实例代码
- Shell脚本中内置命令的解释
- Java泛型详解