udt代码初探

花了一天时间分析了一下UDT的代码,总体感觉代码不是很高深,下面是一些总结

. 报文发送

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_pListenerCUDT::listen处理。

2)     根据目的socketID能查到已经建立好的连接,这样的包还分数据包和控制包两种,分别调用 CUDT::processData , CUDT::processCtrl加以处理.

. 定时器控制

1. 定时器变量和数值

CTimer::rdtsclinux下返回的是微秒(1/ 1000000); 而在windows下则返回一个高精度计数,s_ullCPUFrequency为每微妙高精度计数个数。

经换算,一些变量的默认值:

m_ullSYNInt : 10ms

m_ullACKInt: 10ms 含义应该是一旦收到数据包,那么最多10ms后就会发出ACK

m_iRTT: 初始网络RTT100ms

m_iRTTVar:  初始RTT变幅为 50ms

m_ullNAKInt:  m_iRTT+4×m_iRTTVar 因此初始值为300ms

m_ullMinEXPInt: 初始值为100ms

 

2. 定位器处理

       定时器处理和接收处理共用线程CRcvQueue::worker。底层socketlinux下被设置成了非阻塞,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: 垃圾(如残连接)清理

 

你可能感兴趣的:(linux,windows,socket,网络,buffer)