⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p2pmgr.h

📁 mysee网络直播源代码Mysee Lite是Mysee独立研发的网络视频流媒体播放系统。在应有了P2P技术和一系列先进流媒体技术之后
💻 H
字号:
/*
 *  Openmysee
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
#ifndef __P2P__MGR__H__
#define __P2P__MGR__H__

#include "P2PClient.h"
#include <vector>

namespace NPLayer1 {

enum {
	// 每个NP上的连接数
	MAX_CONNECTION_PER_NP = 1,
	// 每个CP上的连接数
	MAX_CONNECTION_PER_CP = 1,
	// 所有和CP的连接数,这个限制不太严格,只在CSClient::SendNeedPeers中作了限制。
	MAX_CONNECTION_OF_CP = 2,
};
class P2PMgr : public TransferCalculator {
public:
	P2PMgr(Communicator*);
	~P2PMgr();

	// 开始运行
	P2P_RETURN_TYPE Init();
	// 停止运行
	void Uninit();

	// 停止所有连接
	void StopAll();

    // 清除所有连接发送媒体类型区间的记录
    void ClearSentMediaArray();

	// 从现有连接(参数client的连接除外)的Push List中回收一个块
	// 情况1. 某个连接下载到了一个Block,并且在该连接的Push List中没有找到这个块。
	//        那么说明这个块很可能是上次改变Push List之际,对方发送过来的;
	void ReclaimBlocks(P2PClient* client, UINT blockID);

	// 重新分配所有所有连接的Push List.
	// 如果client非NULL,则只分配此连接的块;否则,分配所有连接的块
	void RedistributeAllBlocks(P2PClient* client);

	// 在除了client以外的所有连接的PushList中查找blockID
	bool FindInAllPushList(const UINT blockID, P2PClient* client);

	// 在除了client以外的所有连接(是否包含CP)的remoteInterval中查找blockID
	UINT8 FindInAllRemoteInterval(const blockID, P2PClient* client, bool includeCP, float minSpeed);

	// 在除了client以外的所有LAN连接的remoteInterval中查找blockID
	UINT8 FindInAllLanRemoteInterval(const blockID, P2PClient* client, float minSpeed);

	// 确认一个地址不超过N个连接
	BOOL CheckN4One(P2PAddress addr, bool isForFree, bool isConnected, UINT max);
	// 添加正在连接的连接
	void AddConnecting(const ConnectingPeer& peer);
	// 添加连接成功的连接
	void AddP2PClient(const ConnectingPeer& peer);
	// 添加需要连接的地址
	void AddConnectTo(const P2PAddress& addr, bool connectForFree);
	// 添加连接失败的地址
	void AddBadAddr(P2PAddress addr);
	// 添加Peer信息
	void AddPeerInfo(PeerInfoWithAddr& peer);
	// 获取需要连接的Peer
	BOOL GetPeer4Connect(ConnectingPeer& peer);
	// 向比本机层数更高的Peer广播SPUpdate
	void BroadCastSPUpdate(SPUpdate& spUpdate, BYTE sum);
	// 取得某个已连接Peer有用的Peer列表
	void GetPeersForNeighbour(list<PeerInfoWithAddr> &array, UINT wantNum, P2PAddress& addr);

	// 分配Packet
	TCPPacket* AllocatePacket() { return m_freeList.Allocate(); };
	// 释放Packet
	void ReleasePacket(TCPPacket* packet) { m_freeList.Release(packet); };

	// 取得本机的层数,就是最小的层
	UINT8 GetSelfLayer();
	// 取得本Peer信息
	void GetSelfInfo(CorePeerInfo&);

	// 安全关闭Socket,会启动RunCloseSocket这个线程
	void SafeCloseSocket(SOCKET sock);

	UINT8 GetIncomingCount(bool includeConnecting = false) {return ExGetCount(true, false, false, false, false, includeConnecting);};
	UINT8 GetOutgoingCount(bool includeConnecting = false) {return ExGetCount(false, true, false, false, false, includeConnecting);};
	UINT8 GetFreeInCount(bool includeConnecting = false) {return ExGetCount(false, false, true, false, false, includeConnecting);};
	UINT8 GetFreeOutCount(bool includeConnecting = false) {return ExGetCount(false, false, false, true, false, includeConnecting);};
	UINT8 GetAllInCount(bool includeConnecting = false) {return ExGetCount(true, false, true, false, false, includeConnecting);};
	UINT8 GetAllOutCount(bool includeConnecting = false) {return ExGetCount(false, true, false, true, false, includeConnecting);};
	UINT8 GetAllCount(bool includeConnecting = false) {return ExGetCount(true, true, true, true, false, includeConnecting);};
	UINT8 GetCPConCount(bool includeConnecting = false) {return ExGetCount(true, true, true, true, true, includeConnecting);};
	UINT GetKnownPeerCount() {return m_peers.size();};
	void AddBlockDataUp(UINT i) {m_totalBlockDataUp += i;};
	void AddBlockDataDown(UINT i) {m_totalBlockDataDown += i;};
	void AddCPData(UINT i) {m_totalBytesFromCP += i;};
	LONGLONG GetBlockDataDown() {return m_totalBlockDataDown;};

	// 关于连接的统计
	UINT16 GetLowVersionCount();
	UINT16 GetConnectFailCount();
	UINT16 GetTotalIncomingCount();
	UINT16 GetTotalOutgoingCount();
	UINT16 GetAvgIncomingTime();
	UINT16 GetAvgOutgoingTime();
	void ConnectionEstablished(bool isIncoming);
	void ConnectionClosed(bool isIncoming, DWORD elapsedTime);
	void AddLowVersionConCount() {m_lowversionCount++;};
	float GetMessagePercent();

	// 打印出IP地址
	LPCSTR FormatIPAddress(P2PAddress& addr);

private:
	// 主线程的回调函数
	static void __stdcall RunManager(P2PMgr*);
	// 关闭SOCKET的线程
	static void __stdcall RunCloseSocket(SOCKET* sock);
	// 绑定端口并开始监听
	P2P_RETURN_TYPE Binding();
	// 发送TCP数据包
	void SendPackets();
	// 判断两个Peer是否有建立连接的可能性
	bool IsConnectablePeer(const P2PAddress& connectAddr, const P2PAddress& targetAddr);
	// 取得特定类型的连接数目
	UINT8 ExGetCount(bool in, bool out, bool freeIn, bool freeOut, bool cponly, bool includeConnecting);
	// 检查连接数目是否已满
	bool IsConnectionFull(bool isIncoming, bool isForFree, bool includeConnecting);

	char TempIP[48];

private:
	// 以下单位都是毫秒
	enum { 
		CS_REPORT=5000,				// 定时向TrackServer发送NP的状态
		CS_REPORT2=10000,			// 定时向TrackServer发送NP的状态
		P2P_CONNECT=5000,			// 发出连接的超时时间
		P2P_SEND_REPORT=500,		// 定时向连接中的对方发送自身消息
		P2P_MANAGE=5000,			// 定时检查所有连接,删除超时的连接,并打印传输等状况
		P2P_NEAR_PEERS=60000,		// 定时向连接中节点发送其可能需要的节点信息
		P2P_CLEAR_BADADDR=180000,	// 定时清空无法连接的地址列表,因为有些地址可能值得再次尝试
		TRY_CONNECT=2000,			// 定时检查有没有可以连接的Peer
		P2P_CHECK_PUSHLIST=1000,	// 定时检查所有连接的PushList,如果为空,则重新分配
		LPF_BROADCAST = 10000,      // 定时向局域网广播自己的信息
	};

	SOCKET m_Socket;	// 当前监听的Socket
	BOOL isRunning;		// 是否正在运行
	HANDLE mgrThread;	// 主线程的句柄

	list<P2PClient>			m_clients;		// 所有连接的列表
	list<PeerInfoWithAddr>	m_peers;		// 已知Peer列表
	list<P2PAddress>		m_badAddr;		// 无法连接的地址
	list<ConnectingPeer>	m_connectto;	// 对方要求本机主动连接
	list<ConnectingPeer>	m_connecting;	// 正在连接的Peer

	typedef list<P2PClient>::iterator	ClientIt;

	// TCPPacket动态分配/释放的列表
	FreeList<TCPPacket> m_freeList;	

	// 上传和下载的数据大小(只包括BLOCK数据部分)
	LONGLONG m_totalBlockDataUp, m_totalBlockDataDown;

	// 从CP下载的数据
	LONGLONG m_totalBytesFromCP;

	UINT m_connectFailCount;		// 连接失败的次数
	UINT m_lowversionCount;			// 低版本客户端的连接次数
	UINT m_incomingCount;			// 连入连接成功的次数
	UINT m_outgoingCount;			// 连出连接成功的次数
	UINT m_incomingElapsedTime;		// 所有连入连接存在的总时间
	UINT m_outgoingElapsedTime;		// 所有连入连接存在的总时间

private:
	// 最近一次广播的SelfPeerInfo
	CorePeerInfo lastSent;
public:
	// 最近一次广播之后,块区间发生了变化
	bool m_bBlockIntervalHasChanged;

private:
	Communicator* comm;
};
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -