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;        // 第一个探测分组的到达时间
};

posted on 2018-06-16 18:24  ukernel  阅读(1192)  评论(0编辑  收藏  举报

导航