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_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: 垃圾(如殘連接)清理
?
總結
- 上一篇: 同步与互斥的区别
- 下一篇: 几何基础,多种矩阵的学习,世界坐标到屏幕