• 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;        // 第一个探测分组的到达时间
    };
    
  • 相关阅读:
    OpenStack Trail 部署文档(二)基础服务部署
    OpenStack Trail 部署文档(一)环境规划
    OpenStack Trail 部署文档
    配置kubectl在Mac(本地)远程连接Kubernetes集群
    elasticsearch*3 + Es-Head + kibana Docker集群
    Flex 布局教程:语法篇
    PHP 数组 array_merge 和 数组 + 加号操作的区别
    Redis分布式锁
    Mysql中Exists和In的使用
    让PHP7达到最高性能的几个Tips
  • 原文地址:https://www.cnblogs.com/ukernel/p/9191046.html
Copyright © 2020-2023  润新知