P2PMgr.h
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:8k
源码类别:

P2P编程

开发平台:

Visual C++

  1. /*
  2.  *  Openmysee
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  *
  18.  */
  19. #ifndef __P2P__MGR__H__
  20. #define __P2P__MGR__H__
  21. #include "P2PClient.h"
  22. #include <vector>
  23. namespace NPLayer1 {
  24. enum {
  25. // 每个NP上的连接数
  26. MAX_CONNECTION_PER_NP = 1,
  27. // 每个CP上的连接数
  28. MAX_CONNECTION_PER_CP = 1,
  29. // 所有和CP的连接数,这个限制不太严格,只在CSClient::SendNeedPeers中作了限制。
  30. MAX_CONNECTION_OF_CP = 2,
  31. };
  32. class P2PMgr : public TransferCalculator {
  33. public:
  34. P2PMgr(Communicator*);
  35. ~P2PMgr();
  36. // 开始运行
  37. P2P_RETURN_TYPE Init();
  38. // 停止运行
  39. void Uninit();
  40. // 停止所有连接
  41. void StopAll();
  42.     // 清除所有连接发送媒体类型区间的记录
  43.     void ClearSentMediaArray();
  44. // 从现有连接(参数client的连接除外)的Push List中回收一个块
  45. // 情况1. 某个连接下载到了一个Block,并且在该连接的Push List中没有找到这个块。
  46. //        那么说明这个块很可能是上次改变Push List之际,对方发送过来的;
  47. void ReclaimBlocks(P2PClient* client, UINT blockID);
  48. // 重新分配所有所有连接的Push List.
  49. // 如果client非NULL,则只分配此连接的块;否则,分配所有连接的块
  50. void RedistributeAllBlocks(P2PClient* client);
  51. // 在除了client以外的所有连接的PushList中查找blockID
  52. bool FindInAllPushList(const UINT blockID, P2PClient* client);
  53. // 在除了client以外的所有连接(是否包含CP)的remoteInterval中查找blockID
  54. UINT8 FindInAllRemoteInterval(const blockID, P2PClient* client, bool includeCP, float minSpeed);
  55. // 在除了client以外的所有LAN连接的remoteInterval中查找blockID
  56. UINT8 FindInAllLanRemoteInterval(const blockID, P2PClient* client, float minSpeed);
  57. // 确认一个地址不超过N个连接
  58. BOOL CheckN4One(P2PAddress addr, bool isForFree, bool isConnected, UINT max);
  59. // 添加正在连接的连接
  60. void AddConnecting(const ConnectingPeer& peer);
  61. // 添加连接成功的连接
  62. void AddP2PClient(const ConnectingPeer& peer);
  63. // 添加需要连接的地址
  64. void AddConnectTo(const P2PAddress& addr, bool connectForFree);
  65. // 添加连接失败的地址
  66. void AddBadAddr(P2PAddress addr);
  67. // 添加Peer信息
  68. void AddPeerInfo(PeerInfoWithAddr& peer);
  69. // 获取需要连接的Peer
  70. BOOL GetPeer4Connect(ConnectingPeer& peer);
  71. // 向比本机层数更高的Peer广播SPUpdate
  72. void BroadCastSPUpdate(SPUpdate& spUpdate, BYTE sum);
  73. // 取得某个已连接Peer有用的Peer列表
  74. void GetPeersForNeighbour(list<PeerInfoWithAddr> &array, UINT wantNum, P2PAddress& addr);
  75. // 分配Packet
  76. TCPPacket* AllocatePacket() { return m_freeList.Allocate(); };
  77. // 释放Packet
  78. void ReleasePacket(TCPPacket* packet) { m_freeList.Release(packet); };
  79. // 取得本机的层数,就是最小的层
  80. UINT8 GetSelfLayer();
  81. // 取得本Peer信息
  82. void GetSelfInfo(CorePeerInfo&);
  83. // 安全关闭Socket,会启动RunCloseSocket这个线程
  84. void SafeCloseSocket(SOCKET sock);
  85. UINT8 GetIncomingCount(bool includeConnecting = false) {return ExGetCount(true, false, false, false, false, includeConnecting);};
  86. UINT8 GetOutgoingCount(bool includeConnecting = false) {return ExGetCount(false, true, false, false, false, includeConnecting);};
  87. UINT8 GetFreeInCount(bool includeConnecting = false) {return ExGetCount(false, false, true, false, false, includeConnecting);};
  88. UINT8 GetFreeOutCount(bool includeConnecting = false) {return ExGetCount(false, false, false, true, false, includeConnecting);};
  89. UINT8 GetAllInCount(bool includeConnecting = false) {return ExGetCount(true, false, true, false, false, includeConnecting);};
  90. UINT8 GetAllOutCount(bool includeConnecting = false) {return ExGetCount(false, true, false, true, false, includeConnecting);};
  91. UINT8 GetAllCount(bool includeConnecting = false) {return ExGetCount(true, true, true, true, false, includeConnecting);};
  92. UINT8 GetCPConCount(bool includeConnecting = false) {return ExGetCount(true, true, true, true, true, includeConnecting);};
  93. UINT GetKnownPeerCount() {return m_peers.size();};
  94. void AddBlockDataUp(UINT i) {m_totalBlockDataUp += i;};
  95. void AddBlockDataDown(UINT i) {m_totalBlockDataDown += i;};
  96. void AddCPData(UINT i) {m_totalBytesFromCP += i;};
  97. LONGLONG GetBlockDataDown() {return m_totalBlockDataDown;};
  98. // 关于连接的统计
  99. UINT16 GetLowVersionCount();
  100. UINT16 GetConnectFailCount();
  101. UINT16 GetTotalIncomingCount();
  102. UINT16 GetTotalOutgoingCount();
  103. UINT16 GetAvgIncomingTime();
  104. UINT16 GetAvgOutgoingTime();
  105. void ConnectionEstablished(bool isIncoming);
  106. void ConnectionClosed(bool isIncoming, DWORD elapsedTime);
  107. void AddLowVersionConCount() {m_lowversionCount++;};
  108. float GetMessagePercent();
  109. // 打印出IP地址
  110. LPCSTR FormatIPAddress(P2PAddress& addr);
  111. private:
  112. // 主线程的回调函数
  113. static void __stdcall RunManager(P2PMgr*);
  114. // 关闭SOCKET的线程
  115. static void __stdcall RunCloseSocket(SOCKET* sock);
  116. // 绑定端口并开始监听
  117. P2P_RETURN_TYPE Binding();
  118. // 发送TCP数据包
  119. void SendPackets();
  120. // 判断两个Peer是否有建立连接的可能性
  121. bool IsConnectablePeer(const P2PAddress& connectAddr, const P2PAddress& targetAddr);
  122. // 取得特定类型的连接数目
  123. UINT8 ExGetCount(bool in, bool out, bool freeIn, bool freeOut, bool cponly, bool includeConnecting);
  124. // 检查连接数目是否已满
  125. bool IsConnectionFull(bool isIncoming, bool isForFree, bool includeConnecting);
  126. char TempIP[48];
  127. private:
  128. // 以下单位都是毫秒
  129. enum { 
  130. CS_REPORT=5000, // 定时向TrackServer发送NP的状态
  131. CS_REPORT2=10000, // 定时向TrackServer发送NP的状态
  132. P2P_CONNECT=5000, // 发出连接的超时时间
  133. P2P_SEND_REPORT=500, // 定时向连接中的对方发送自身消息
  134. P2P_MANAGE=5000, // 定时检查所有连接,删除超时的连接,并打印传输等状况
  135. P2P_NEAR_PEERS=60000, // 定时向连接中节点发送其可能需要的节点信息
  136. P2P_CLEAR_BADADDR=180000, // 定时清空无法连接的地址列表,因为有些地址可能值得再次尝试
  137. TRY_CONNECT=2000, // 定时检查有没有可以连接的Peer
  138. P2P_CHECK_PUSHLIST=1000, // 定时检查所有连接的PushList,如果为空,则重新分配
  139. LPF_BROADCAST = 10000,      // 定时向局域网广播自己的信息
  140. };
  141. SOCKET m_Socket; // 当前监听的Socket
  142. BOOL isRunning; // 是否正在运行
  143. HANDLE mgrThread; // 主线程的句柄
  144. list<P2PClient> m_clients; // 所有连接的列表
  145. list<PeerInfoWithAddr> m_peers; // 已知Peer列表
  146. list<P2PAddress> m_badAddr; // 无法连接的地址
  147. list<ConnectingPeer> m_connectto; // 对方要求本机主动连接
  148. list<ConnectingPeer> m_connecting; // 正在连接的Peer
  149. typedef list<P2PClient>::iterator ClientIt;
  150. // TCPPacket动态分配/释放的列表
  151. FreeList<TCPPacket> m_freeList;
  152. // 上传和下载的数据大小(只包括BLOCK数据部分)
  153. LONGLONG m_totalBlockDataUp, m_totalBlockDataDown;
  154. // 从CP下载的数据
  155. LONGLONG m_totalBytesFromCP;
  156. UINT m_connectFailCount; // 连接失败的次数
  157. UINT m_lowversionCount; // 低版本客户端的连接次数
  158. UINT m_incomingCount; // 连入连接成功的次数
  159. UINT m_outgoingCount; // 连出连接成功的次数
  160. UINT m_incomingElapsedTime; // 所有连入连接存在的总时间
  161. UINT m_outgoingElapsedTime; // 所有连入连接存在的总时间
  162. private:
  163. // 最近一次广播的SelfPeerInfo
  164. CorePeerInfo lastSent;
  165. public:
  166. // 最近一次广播之后,块区间发生了变化
  167. bool m_bBlockIntervalHasChanged;
  168. private:
  169. Communicator* comm;
  170. };
  171. }
  172. #endif