UDT源码剖析(三)之数据结构

本节介绍在UDT源代码中所有使用的数据结构

CUDTSocket:描述UDT SOCKET

class CUDTSocket
{
   UDTSTATUS m_Status;                       //当前UDT SOCKET的状态

   uint64_t m_TimeStamp;                     //UDT SOCKET关闭的时间

   int m_iIPversion;                         //IP Version
   sockaddr* m_pSelfAddr;                    // pointer to the local address of the socket
   sockaddr* m_pPeerAddr;                    // pointer to the peer address of the socket

   UDTSOCKET m_SocketID;                     // socket ID
   UDTSOCKET m_ListenSocket;                 // ID of the listener socket; 0 means this is an independent socket

   UDTSOCKET m_PeerID;                       // peer socket ID
   int32_t m_iISN;                           //初始化序列号,用来告知来自相同的IP:Port的不同的连接

   CUDT* m_pUDT;                             // pointer to the UDT entity

   std::set<UDTSOCKET>* m_pQueuedSockets;    //连接已完成,等待accept()调用的队列
   std::set<UDTSOCKET>* m_pAcceptSockets;    //已经完成accept()的队列

   udt_pthread_cond_t m_AcceptCond;              // used to block "accept" call
   udt_pthread_mutex_t m_AcceptLock;             // mutex associated to m_AcceptCond

   unsigned int m_uiBackLog;                 //Listener中的最大连接数

   int m_iMuxID;                             //资源复用器ID

   udt_pthread_mutex_t m_ControlLock;            // lock this socket exclusively for control APIs: bind/listen/connect

private:
   CUDTSocket(const CUDTSocket&);
   CUDTSocket& operator=(const CUDTSocket&);
};

UDTSTATUS:描述UDT SOCKET状态

enum UDTSTATUS {INIT = 1, OPENED, LISTENING, CONNECTING, CONNECTED, BROKEN, CLOSING, CLOSED, NONEXIST};

CUDTUnited:全局管理者,保存所有的UDT SOCKET

class CUDTUnited
{
   std::map<UDTSOCKET, CUDTSocket*> m_Sockets;       //保存所有的UDT SOCKET实例

   udt_pthread_mutex_t m_ControlLock;                

   udt_pthread_mutex_t m_IDLock;                    
   UDTSOCKET m_SocketID;                             //每一次启动时都会创建一个唯一的SOCKET ID

   std::map<int64_t, std::set<UDTSOCKET> > m_PeerRec;    //记录来自对方套接字的连接以避免重读的请求,int64_t = (socker_id << 30) + isn

private:
   udt_pthread_key_t m_TLSError;                     //线程局部的错误反馈,还不如使用全局变量呢..
   #ifndef WINDOWS
      static void TLSDestroy(void* e) {if (NULL != e) delete (CUDTException*)e;}
   #else
      std::map<DWORD, CUDTException*> m_mTLSRecord;
      void checkTLSValue();
      udt_pthread_mutex_t m_TLSLock;
   #endif

private:
   std::map<int, CMultiplexer> m_mMultiplexer;      // UDP multiplexer(复用器),不过我一直没有搞懂代表什么意思
   udt_pthread_mutex_t m_MultiplexerLock;

private:
   CCache<CInfoBlock>* m_pCache;            // UDT network information cache

private:
   volatile bool m_bClosing;    //目前的状态是否为关闭的,主要用于调整GC线程
   udt_pthread_mutex_t m_GCStopLock;
   udt_pthread_cond_t m_GCStopCond;

   udt_pthread_mutex_t m_InitLock;
   int m_iInstanceCount;                //记录调用startup()的次数
   bool m_bGCStatus;                    //判断GC线程是否在工作

   udt_pthread_t m_GCThread;
   #ifndef WINDOWS
      static void* garbageCollect(void*);    
   #else
      static DWORD WINAPI garbageCollect(LPVOID);
   #endif

   std::map<UDTSOCKET, CUDTSocket*> m_ClosedSockets;   //暂时存放关闭的UDT SOCKET

   void checkBrokenSockets();
   void removeSocket(const UDTSOCKET u);

private:
   CEPoll m_EPoll;                                     //事件处理器

private:
   CUDTUnited(const CUDTUnited&);
   CUDTUnited& operator=(const CUDTUnited&);
};

CMultiplexer:资源复用器,他是所有资源的实际所有者,其他的都只是引用(目前我是这样理解的)

struct CMultiplexer
{
   CSndQueue* m_pSndQueue;  // The sending queue
   CRcvQueue* m_pRcvQueue;  // The receiving queue
   CChannel* m_pChannel;    // The UDP channel for sending and receiving
   CTimer* m_pTimer;        // The timer

   int m_iPort;         // The UDP port number of this multiplexer
   int m_iIPversion;        // IP version
   int m_iMSS;          // Maximum Segment Size
   int m_iRefCount;     //与此资源复用器相关联的UDT实例的数量
   bool m_bReusable;        //这个资源复用器是否可以被共享

   int m_iID;           // multiplexer ID
};

CCache:使用HASH缓存信息(Vector+List)

template<typename T> class CCache               
{
private:
   std::list<T*> m_StorageList;
   typedef typename std::list<T*>::iterator ItemPtr;
   typedef std::list<ItemPtr> ItemPtrList;
   std::vector<ItemPtrList> m_vHashPtr;

   int m_iMaxSize;    //1024
   int m_iHashSize;        //1024*3
   int m_iCurrSize;    //0

   udt_pthread_mutex_t m_Lock;

private:
   CCache(const CCache&);
   CCache& operator=(const CCache&);
};

CInfoBlock

class CInfoBlock
{
public:
   uint32_t m_piIP[4];      //机器可读的IP地址,为了IPV4只占32位,IPV6全部占用
   int m_iIPversion;        // IP version
   uint64_t m_ullTimeStamp; //上一次更新的时间
   int m_iRTT;          //RTT
   int m_iBandwidth;        //估计的带宽
   int m_iLossRate;     //平均丢失速率
   int m_iReorderDistance;  //数据包重新排序距离
   double m_dInterval;      //分组间时间,就是数据包发送的间隔时间,用于拥塞控制
   double m_dCWnd;      //拥塞窗口大小用于拥塞控制
}

CEpoll:别具一格的EPoll,存在一组EPoll管理一组事件

class CEPoll
{
   int m_iIDSeed;                            //new时创建的随机ID
   udt_pthread_mutex_t m_SeedLock;

   std::map<int, CEPollDesc> m_mPolls;       // all epolls
   udt_pthread_mutex_t m_EPollLock;
};

CEPollDesc:描述具体关注的事件:人为管理的UDT事件以及系统管理的UDP事件

struct CEPollDesc
{
   int m_iID;                                // epoll ID
   std::set<UDTSOCKET> m_sUDTSocksOut;       // set of UDT sockets waiting for write events
   std::set<UDTSOCKET> m_sUDTSocksIn;        // set of UDT sockets waiting for read events
   std::set<UDTSOCKET> m_sUDTSocksEx;        // set of UDT sockets waiting for exceptions

   int m_iLocalID;                           // local system epoll ID
   std::set<SYSSOCKET> m_sLocals;            // set of local (non-UDT) descriptors

   std::set<UDTSOCKET> m_sUDTWrites;         // UDT sockets ready for write
   std::set<UDTSOCKET> m_sUDTReads;          // UDT sockets ready for read
   std::set<UDTSOCKET> m_sUDTExcepts;        // UDT sockets with exceptions (connection broken, etc.)
};

CUDT:全局最复杂的一个类,用于描述一个UDT连接

class CUDT {
    static CUDTUnited s_UDTUnited;                  //静态变量,所有的CUDT共享的全局管理对象
public:
    static const UDTSOCKET INVALID_SOCK;            //初始化无效的UDT SOCKET = -1
    static const int ERROR;                                 //初始化错误
private:
    UDTSOCKET       m_SocketID;                     // UDT socket number
    UDTSockType     m_iSockType;                    //TCP /  UDP
    UDTSOCKET       m_PeerID;                   // peer id, for multiplexer
    static const int m_iVersion;                            // UDT version, for compatibility use
private:
    int             m_iPktSize;                             // Maximum/regular packet size, in bytes
    int             m_iPayloadSize;                         // Maximum/regular payload(有效载荷) size, in bytes
private:
    int             m_iMSS;                         // Maximum Segment Size, in bytes
    bool            m_bSynSending;                  // 发送同步模式
    bool            m_bSynRecving;                  // 接收同步模式
    int             m_iFlightFlagSize;                      // 来自对端的最大的数据包传输量
    int             m_iSndBufSize;                  //UDT最大的发送缓冲大小
    int             m_iRcvBufSize;                  //UDT最大的接收缓冲区大小
    linger          m_Linger;                   //如果使用了Linger选项,Struct Linger
    int             m_iUDPSndBufSize;               //UDP发送缓冲区大小
    int             m_iUDPRcvBufSize;               //UDP接收缓冲区大小
    int             m_iIPversion;                           // IP version
    bool            m_bRendezvous;                  //交会连接模式
    int             m_iSndTimeOut;                  //发送超时时间(ms)
    int             m_iRcvTimeOut;                  //接收超时时间(ms)
    bool            m_bReuseAddr;                   //是否重用UDP端口
    int64_t         m_llMaxBW;                      //最大的数据传输速率(阀值)
private:
    CCCVirtualFactory * m_pCCFactory;               // 为了提供特殊的拥塞控制接口
    CCC *           m_pCC;                      // 拥塞控制接口
    CCache < CInfoBlock > *m_pCache;                // 管理连接缓存
private:
    volatile bool   m_bListening;                           // 是否正在监听中?
    volatile bool   m_bConnecting;                  // 是否处于连接中?连接未完成
    volatile bool   m_bConnected;                   // 连接已完成
    volatile bool   m_bClosing;                             // 是否处于关闭过程中?未完成
    volatile bool   m_bShutdown;                    // 对方的连接是否调用了shutdown?
    volatile bool   m_bBroken;                      // 连接是否已经损坏?
    volatile bool   m_bPeerHealth;                  // 对等方是否依旧正常?
    bool            m_bOpened;                      // UDT是否已经打开?
    int             m_iBrokenCounter;                       // 一个计数器,记录目前处于Broken状态的UDT SOCKET,由GC线程使用
    int             m_iEXPCount;                    // 异常计数器
    int             m_iBandwidth;                   // 估计带宽(packets / second)
    int             m_iRTT;                                 // RTT(ms)
    int             m_iRTTVar;                      // RTT方差
    int             m_iDeliveryRate;                        // 对方的接收速率(packets / second)
    uint64_t        m_ullLingerExpiration;                  //异常连接终止时的等待时间
    CHandShake      m_ConnReq;                  // connection request
    CHandShake      m_ConnRes;                  // connection response
    int64_t         m_llLastReqTime;                        // last time when a connection request is sent
private:
    CSndBuffer *    m_pSndBuffer;                   // Sender buffer(SendQueue是针对UDP使用的,SendBuffer是针对UDT使用的)
    CSndLossList *  m_pSndLossList;                 // Sender loss list
    CPktTimeWindow * m_pSndTimeWindow;          // 数据包发送时间窗口

    volatile uint64_t m_ullInterval;                                //数据包发送时间间隔, 使用CPU周期计数
    uint64_t        m_ullTimeDiff;                          // 数据包间时间的差异

    volatile int    m_iFlowWindowSize;              // 流量控制窗口大小
    volatile double m_dCongestionWindow;                    // 拥塞窗口大小

    volatile int32_t m_iSndLastAck;                         // 上一次收到的ACK序列号
    volatile int32_t m_iSndLastDataAck;                     // 最后一个用于更新发送缓冲区和丢失链表的ACK
    volatile int32_t m_iSndCurrSeqNo;                       // 已发送的最大的序列号
    int32_t         m_iLastDecSeq;                  // 发送的最后一次减少的序列号
    int32_t         m_iSndLastAck2;                         // 最后送回的ACK2
    uint64_t        m_ullSndLastAck2Time;                   // 最后送回的ACK2的时间
    int32_t         m_iISN;                                 // 初始序列号
private:
    CRcvBuffer *    m_pRcvBuffer;                   // Receiver buffer
    CRcvLossList *  m_pRcvLossList;                 // Receiver loss list
    CACKWindow *    m_pACKWindow;               // 收到的ACK历史窗口
    CPktTimeWindow * m_pRcvTimeWindow;          // 数据包到达时间窗口

    int32_t         m_iRcvLastAck;                  // 上一次接收的ACK
    uint64_t        m_ullLastAckTime;                       // 上一次接收ACK的时间
    int32_t         m_iRcvLastAckAck;               // 最后接收的已确认的ACK
    int32_t         m_iAckSeqNo;                    // 最后接收的ACK序列号
    int32_t         m_iRcvCurrSeqNo;                        // 收到的最大的序列号
    uint64_t        m_ullLastWarningTime;                   // 上一次收到警告信息的时间
    int32_t         m_iPeerISN;                             //  对方的初始化序列号
private:
    udt_pthread_mutex_t m_ConnectionLock;           // used to synchronize connection operation

    udt_pthread_cond_t m_SendBlockCond;             // used to block "send" call
    udt_pthread_mutex_t m_SendBlockLock;            // lock associated to m_SendBlockCond

    udt_pthread_mutex_t m_AckLock;                  // used to protected sender's loss list when processing ACK

    udt_pthread_cond_t m_RecvDataCond;              // used to block "recv" when there is no data
    udt_pthread_mutex_t m_RecvDataLock;             // lock associated to m_RecvDataCond

    udt_pthread_mutex_t m_SendLock;                 // used to synchronize "send" call
    udt_pthread_mutex_t m_RecvLock;                 // used to synchronize "recv" call
private:
    uint64_t        m_StartTime;                            // UDT的启动时间
    int64_t         m_llSentTotal;                          // 发送的数据包总数,包括重传
    int64_t         m_llRecvTotal;                          // 收到的数据包总数
    int             m_iSndLossTotal;                        // 发送端丢失的数据包总数
    int             m_iRcvLossTotal;                        // 接收端丢失的数据包总数
    int             m_iRetransTotal;                        // 重传的数据包总数
    int             m_iSentACKTotal;                        // 发送的ACK数据包总数
    int             m_iRecvACKTotal;                        // 收到的ACK数据包总数
    int             m_iSentNAKTotal;                        // 发送的NAK数据包总数
    int             m_iRecvNAKTotal;                        // 收到的NAK数据包总数
    int64_t         m_llSndDurationTotal;                   // 总的实时发送时间

    uint64_t        m_LastSampleTime;               // 最后的性能采样时间
    int64_t         m_llTraceSent;                  // 在最后一个跟踪的时间间隔内发送的数据包数量
    int64_t         m_llTraceRecv;                  // 在最后一个跟踪的时间间隔内接收的数据包总量
    int             m_iTraceSndLoss;                        // 发送端在最后一个跟踪的时间间隔内发送的数据包数量
    int             m_iTraceRcvLoss;                        // 接收端的最后一个跟踪的时间间隔内接收的数据包数量
    int             m_iTraceRetrans;                        // 在最后一个跟踪的时间间隔内重传的数据包数量
    int             m_iSentACK;                             // 在最后一个跟踪的时间间隔内发送的ACK数据包数量
    int             m_iRecvACK;                             // 在最后一个跟踪的时间间隔内接受的ACK数据包数量
    int             m_iSentNAK;                             // 在最后一个跟踪的时间间隔内发送的NAK数据包数量
    int             m_iRecvNAK;                             // 在最后一个跟踪的时间间隔内接收的NAK数据包数量
    int64_t         m_llSndDuration;                        // 发送真正花费的时间
    int64_t         m_llSndDurationCounter;                 // 使用定时器来记录持续发送的时间
private:
    uint64_t        m_ullCPUFrequency;              // CPU时钟频率, used for Timer, ticks per microsecond
    static const int m_iSYNInterval;                        // 周期性速率控制间隔, 10000 microsecond
    static const int m_iSelfClockInterval;                  // ACK时钟间隔
    uint64_t        m_ullNextACKTime;               // 下一次ACK到期时间,使用CPU时钟周期
    uint64_t        m_ullNextNAKTime;               // 下一次NAK到期时间,使用CPU时钟周期
    volatile uint64_t m_ullSYNInt;                          // SYN时间间隔,使用CPU时钟周期
    volatile uint64_t m_ullACKInt;                          // ACK时间间隔,使用CPU时钟周期
    volatile uint64_t m_ullNAKInt;                          // NAK时间间隔,使用CPU时钟周期
    volatile uint64_t m_ullLastRspTime;                     // 对方最后一次回复的时间
    uint64_t        m_ullMinNakInt;                         // NAK超时下限,太小的值可能会引起不必要的重传
    uint64_t        m_ullMinExpInt;                         // 超时下限阀值,太小的值会导致问题
    int             m_iPktCount;                            // 收到的ACK计数
    int             m_iLightACKCount;               // 轻量级的ACK计数
    uint64_t        m_ullTargetTime;                        // 下一个数据包发送的预计时间
private:
    // for UDP multiplexer
    CSndQueue *     m_pSndQueue;                    // 数据包发送队列
    CRcvQueue *     m_pRcvQueue;                    // 数据包接收队列
    sockaddr *      m_pPeerAddr;                    // 对方的地址
    uint32_t        m_piSelfIP[4];                          // 本地的IP地址
    CSNode *        m_pSNode;                       // 发送队列Node(堆)
    CRNode *        m_pRNode;                   // 接收队列Node(双向链表)
private:
    std::set < int > m_sPollID;                             //所有的EpollID 
};

CSndBuffer:UDT SOCKET Send Buffer

class CSndBuffer
{
private:
   udt_pthread_mutex_t m_BufLock;           // used to synchronize buffer operation

   struct Block    //为了方便的提交给SendQueue
   {
      char* m_pcData;                   // 指向数据块
      int m_iLength;                       // 数据块的长度
      int32_t m_iMsgNo;                // 数据块的编号
      uint64_t m_OriginTime;         // 原始请求时间
      int m_iTTL;                            // TTL(ms)

      Block* m_pNext;                   // next block
   } *m_pBlock, *m_pFirstBlock, *m_pCurrBlock, *m_pLastBlock;

   // m_pBlock:         The head pointer
   // m_pFirstBlock:    The first block
   // m_pCurrBlock: The current block
   // m_pLastBlock:     The last block (if first == last, buffer is empty)

   struct Buffer    //真实的存储Buffer
   {
      char* m_pcData;           // buffer
      int m_iSize;                  // size
      Buffer* m_pNext;          // next buffer
   } *m_pBuffer;                    // physical buffer

   int32_t m_iNextMsgNo;                //下一条消息编号

   int m_iSize;                     // 32 (number of packets)
   int m_iMSS;                                  // 1500
   int m_iCount;                    // 已经使用的Blocks
};

CRecvBuffer:UDT SOCKET Recv Buffer

class CRcvBuffer
{
private:
   CUnit** m_pUnit;                           // 数据缓冲Buffer
   int m_iSize;                                   // 65536(bytes)
   CUnitQueue* m_pUnitQueue;      // 共享的接收队列
   int m_iStartPos;                            // 开始读取data的位置
   int m_iLastAckPos;                       // 上一次被确认的位置,start~lastpos之间的数据可读
                                                        // EMPTY: m_iStartPos = m_iLastAckPos   FULL: m_iStartPos = m_iLastAckPos + 1
   int m_iMaxPos;                   // 数据存在的最大的位置,还没有被确认
   int m_iNotch;                    // 第一个CUnit的读取点
};

CPacket:数据包的封装

class CPacket
{
public:
   int32_t& m_iSeqNo;                       // sequence number
   int32_t& m_iMsgNo;                       // message number
   int32_t& m_iTimeStamp;                // timestamp
   int32_t& m_iID;                    // socket ID
   char*& m_pcData;                          // data/control information

   static const int m_iPktHdrSize;    // packet header size = 16

protected:
   uint32_t m_nHeader[4];               // The 128-bit header field
   iovec m_PacketVector[2];             // The 2-demension vector of UDT packet [header, data]

   int32_t __pad;
};

CHandShake:握手包

class CHandShake
{
public:
   static const int m_iContentSize; // Size of hand shake  = 48

public:
   int32_t m_iVersion;               // UDT version
   int32_t m_iType;                   // UDT socket type:TCP/UDP
   int32_t m_iISN;                     // 随机的初始化序列号
   int32_t m_iMSS;                   // maximum segment size
   int32_t m_iFlightFlagSize;    // flow control window size
   int32_t m_iReqType;            // 1: regular connection request, 0: rendezvous(交会连接请求) connection request, -1/-2: response
   int32_t m_iID;               // socket ID
   int32_t m_iCookie;           // cookie
   uint32_t m_piPeerIP[4];       // The IP address that the peer's UDP port is bound to
};

CUnit:对于Packet的简单封装

struct CUnit
{
   CPacket m_Packet;        // packet
   int m_iFlag;                 // 0: free 1:occupid, 2: msg已经read,但是还没有被free, 3: msg被丢弃
};

CUnitQueue:类似HASH那样组织CUnit Queue

class CUnitQueue
{
private:
   struct CQEntry
   {
      CUnit* m_pUnit;       // unit queue
      char* m_pBuffer;      // data buffer
      int m_iSize;      // size of each queue

      CQEntry* m_pNext;
   }
   *m_pQEntry,          // 指向起始的Entry队列
   *m_pCurrQueue,       // 指向当前的Entry队列
   *m_pLastQueue;       // 指向最后一个Entry队列

   CUnit* m_pAvailUnit;         //最近访问的Unit* 
   int m_iSize;         // 总共的Packets数量
   int m_iCount;        // 已经使用的Packets数量
   int m_iMSS;          // unit buffer size
   int m_iIPversion;        // IP version
};

CSNode:Send List Node

struct CSNode
{
   CUDT* m_pUDT;                // 指向CUDT*的指针
   uint64_t m_llTimeStamp;     // 堆化时排序的时间戳

   int m_iHeapLoc;              // 堆的层次,-1意味着暂时不存在与当前堆中
};

CSndList:Send List,使用堆对即将发送的packet进行组织

class CSndUList
{
private:
   CSNode** m_pHeap;                            // 堆化数组
   int m_iArrayLength;                          // 堆数组长度
   int m_iLastEntry;                                    // 最近一次发送的位置
   udt_pthread_mutex_t m_ListLock;               
   udt_pthread_mutex_t* m_pWindowLock;     
   udt_pthread_cond_t* m_pWindowCond;         
   CTimer* m_pTimer;
};

CRNode:Recv List Node

struct CRNode
{
   CUDT* m_pUDT;                // Pointer to CUDT*
   uint64_t m_llTimeStamp;      // Time Stamp

   CRNode* m_pPrev;             // previous link
   CRNode* m_pNext;             // next link

   bool m_bOnList;              // 当前节点是否在双向链表上
};

CRcvUList:用于接收packet的双向链表

class CRcvUList
{
public:
   CRNode* m_pUList;        // the head node
private:
   CRNode* m_pLast;     // the last node
};

CHash:Hash表

class CHash
{
private:
   struct CBucket
   {
      int32_t m_iID;        // Socket ID
      CUDT* m_pUDT;     // Socket instance

      CBucket* m_pNext;     // next bucket
   } **m_pBucket;       // list of buckets (the hash table)

   int m_iHashSize;     // size of hash table
};

CRendezvousQueue:交汇连接队列

class CRendezvousQueue
{
private:
   struct CRL
   {
      UDTSOCKET m_iID;          // UDT socket ID (self)
      CUDT* m_pUDT;         // UDT instance
      int m_iIPversion;                 // IP version
      sockaddr* m_pPeerAddr;        // UDT sonnection peer address
      uint64_t m_ullTTL;            // the time that this request expires
   };
   std::list<CRL> m_lRendezvousID;      // The sockets currently in rendezvous mode

   udt_pthread_mutex_t m_RIDVectorLock;
};

CSndQueue:Send Queue

class CSndQueue
{
private:
   static void* worker(void* param);        //发送线程
   udt_pthread_t m_WorkerThread;

private:
   CSndUList* m_pSndUList;          // 堆化的Send List
   CChannel* m_pChannel;                 // The UDP channel for data sending
   CTimer* m_pTimer;                // 定时器设施

   udt_pthread_mutex_t m_WindowLock;
   udt_pthread_cond_t m_WindowCond;

   volatile bool m_bClosing;        // 发送线程是否启动
   udt_pthread_cond_t m_ExitCond;
};

CRcvQueue:Recv Queue

class CRcvQueue
{
private:
   static void* worker(void* param);    //接收线程
   udt_pthread_t m_WorkerThread;

private:
   CUnitQueue m_UnitQueue;      // The received packet queue(就是那个类似于Hash的组织)

   CRcvUList* m_pRcvUList;      // 这个List中的UDT实例准备从Queue中读取数据
   CHash* m_pHash;          // HASH可以加速在List中寻找UDT实例
   CChannel* m_pChannel;        // UDP channel for receving packets
   CTimer* m_pTimer;            // 与发送队列共享Timer

   int m_iPayloadSize;                      // packet中的有效载荷

   volatile bool m_bClosing;              // 接收线程是否启动
   udt_pthread_cond_t m_ExitCond;

private:
   udt_pthread_mutex_t m_LSLock;
   CUDT* m_pListener;                                   // pointer to the (unique, if any) listening UDT entity
   CRendezvousQueue* m_pRendezvousQueue;                // 汇合模式中的UDT SOCKET列表

   std::vector<CUDT*> m_vNewEntry;                                  // 新添加的条目
   udt_pthread_mutex_t m_IDLock;

   std::map<int32_t, std::queue<CPacket*> > m_mBuffer;  // 用于集合连接请求的临时缓冲区
   udt_pthread_mutex_t m_PassLock;
   udt_pthread_cond_t m_PassCond;
};

CChannel:描述UDP,用于数据发送

class CChannel
{
 private:
   int m_iIPversion;                    // IP version
   int m_iSockAddrSize;                 // socket address structure size (pre-defined to avoid run-time test)

   UDPSOCKET m_iSocket;                 // socket descriptor

   int m_iSndBufSize;                   // UDP sending buffer size
   int m_iRcvBufSize;                   // UDP receiving buffer size
};

CTimer:定时器设施

class CTimer
{
private:
   uint64_t m_ullSchedTime;             //下一次被调度的时间

   udt_pthread_cond_t m_TickCond;
   udt_pthread_mutex_t m_TickLock;

   static udt_pthread_cond_t m_EventCond;
   static udt_pthread_mutex_t m_EventLock;

private:
   static uint64_t s_ullCPUFrequency;   // CPU的时钟频率
   static uint64_t readCPUFrequency();
   static bool m_bUseMicroSecond;       // use gettimeofday().
};

CACKWindow:记录ACK时间的窗口

class CACKWindow
{
private:
   int32_t* m_piACKSeqNo;       // 记录ACK序列号
   int32_t* m_piACK;            // 记录数据序列号
   uint64_t* m_pTimeStamp;      //记录ACK的发送时间

   int m_iSize;                 // ACK窗口的大小
   int m_iHead;                 // 记录最后一次ACK
   int m_iTail;                 // 记录存在时间最长的ACK
};

CPktTimeWindow:记录数据包的时间窗口

class CPktTimeWindow
{
private:
   int m_iAWSize;                   // 分组到达时历史窗口的大小
   int* m_piPktWindow;          // 分组信息窗口
   int* m_piPktReplica;
   int m_iPktWindowPtr;         // 分组信息窗口的位置指针

   int m_iPWSize;               // 探测历史窗口打下
   int* m_piProbeWindow;        // 记录用于探测分组的分组间时间
   int* m_piProbeReplica;
   int m_iProbeWindowPtr;       // 位置指针指向探测窗口

   int m_iLastSentTime;         // 最后一个packet的发送时间
   int m_iMinPktSndInt;         // 最小的包发送时间间隔

   uint64_t m_LastArrTime;      // 最后一个包的到达时间
   uint64_t m_CurrArrTime;      // 当前包的到达时间
   uint64_t m_ProbeTime;        // 第一个探测分组的到达时间
};

猜你喜欢

转载自www.cnblogs.com/ukernel/p/9191046.html