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

📄 udptracker.cpp

📁 这是一个嵌入式linux系统下的BT下载工具包
💻 CPP
字号:
/*************************************************************************** *   Copyright (C) 2005-2006 Gao Xianchao                                  * *                 2007 Gao Xianchao gnap_an linux_lyb ahlongxp            * *                                                                         * *   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.             * ***************************************************************************//* * Author:	gxc * Create data:	2005-10-26 20:09 */ #include <unistd.h>#include <netdb.h>#include <stdlib.h>#include <arpa/inet.h>#include "UDPTracker.h"#include "utils.h"#include "log.h"#pragma pack(push,1)typedef struct{	int64_t connection_id;	unsigned int action_id;	unsigned int transaction_id;} TConnectPacket;typedef struct{	int64_t connection_id;	unsigned int action_id;	unsigned int transaction_id;		char info_hash[20];	char peer_id[20];	int64_t downloaded;	int64_t left;	int64_t uploaded;	unsigned int event;	unsigned int ip;	unsigned int key;	int num_want;	unsigned short port;	unsigned short extensions;} TAnnouncPacket;#pragma pack(pop)#define RECV_BUFFER_SIZE		8*1024CUDPTracker::CUDPTracker(){	_state = TS_INIT;	memset(&_serverAddr, 0, sizeof(_serverAddr));	_completePeer = 0;	_totalPeer = 0;	_interval = 0;	_nextUpdateTick = GetTickCount();}CUDPTracker::~CUDPTracker(){}void CUDPTracker::setTrackerManager(ITrackerManager* trackerManager){	_trackerManager = trackerManager;}bool CUDPTracker::isProtocolSupported(const char* protocolName){	if(strcmp(protocolName, "udp") == 0		|| strcmp(protocolName, "UDP") == 0)	{		return true;	}		return false;}void CUDPTracker::setUrl(const char* url){	_url = url;}void CUDPTracker::update(){	if(_state == TS_INIT)	{		if(_serverAddr.sin_port == 0)		{			srand(GetTickCount());						//gethostbyname			std::string host;			std::string path;			unsigned short port;			if(!parseUrl(_url.c_str(), host, &port, path))			{				_state = TS_ERROR;				_stateStr = "Tracker URL error";				_interval = GetTickCount() + 60*60*1000;				return;			}						struct hostent* hptr = gethostbyname(host.c_str());			if(hptr == NULL)			{				_state = TS_ERROR;				_stateStr = "Can not find host : " + host;						_interval = GetTickCount() + 60*1000;				return;							}						_serverAddr.sin_family = AF_INET;			_serverAddr.sin_addr.s_addr = *((in_addr_t *)hptr->h_addr_list[0]);			_serverAddr.sin_port = htons(port);		}						CSocket::createUDPSocket();		CSocket::setReactor(_trackerManager->getBTTask()->getSocketReactor());		maskRead(true);				sendConnectPacket();				_state = TS_CONNECTING;		_nextUpdateTick = GetTickCount() + 15*1000;			}		if(_state == TS_ERROR		|| _state == TS_CONNECTING)	{		sendConnectPacket();				_state = TS_CONNECTING;		_nextUpdateTick = GetTickCount() + 15*1000;				}		if(_state == TS_OK		|| _state == TS_REQUESTING)	{		sendAnnouncPacket();	}}void CUDPTracker::stop(){	CSocket::setReactor(NULL);	CSocket::close();}TTrackerState CUDPTracker::getState(){	return _state;}const std::string& CUDPTracker::getStateStr(){	return _stateStr;}unsigned int CUDPTracker::getSeedCount(){	return _completePeer;}unsigned int CUDPTracker::getPeerCount(){	return _totalPeer;}unsigned int CUDPTracker::getInterval(){	return _interval;}unsigned int CUDPTracker::getNextUpdateTick(){	return _nextUpdateTick;}int CUDPTracker::handleRead(){	char* buf = new char[RECV_BUFFER_SIZE];	struct sockaddr_in addr;	memset(&addr, 0, sizeof(addr));	socklen_t len = (socklen_t)sizeof(addr);		int ret = recvfrom(getHandle(), buf, RECV_BUFFER_SIZE, 0, (struct sockaddr*)&addr, &len);	LOG_DEBUG("recvfrom return "<<ret);	if(addr.sin_addr.s_addr == _serverAddr.sin_addr.s_addr 		&& ret > 8)	{		unsigned int actionID = *((unsigned int*)buf);		actionID = ntohl(actionID);				unsigned int transID = *((unsigned int*)(buf+4));		transID = ntohl(transID);				if(transID == _transID)		{			processPkg(actionID, buf+8, ret - 8);		}	}		delete[] buf;		return 0;}int CUDPTracker::handleWrite(){	return 0;}void CUDPTracker::handleClose(){}void CUDPTracker::sendConnectPacket(){	_transID = rand() * GetTickCount();		TConnectPacket pkg;		pkg.connection_id = 0x41727101980LL;	pkg.connection_id = htonll(pkg.connection_id);	pkg.action_id = 0;	pkg.transaction_id = htonl(_transID);		int ret = sendto(getHandle(), &pkg, sizeof(pkg), 0, (const struct sockaddr*)&_serverAddr, sizeof(_serverAddr));	LOG_DEBUG("sendto return "<<ret);}void CUDPTracker::sendAnnouncPacket(){	_transID = rand() * GetTickCount();		TAnnouncPacket pkg;		pkg.connection_id = htonll(_connectionID);	pkg.action_id = htonl(1);	pkg.transaction_id = htonl(_transID);	memcpy(pkg.info_hash, _trackerManager->getBTTask()->getTorrentFile()->getInfoHash(), 20);	memcpy(pkg.peer_id,  _trackerManager->getBTTask()->getPeerID().c_str(), 20);	pkg.downloaded = htonl(_trackerManager->getBTTask()->getDownlaodCount());	pkg.left = htonl(_trackerManager->getBTTask()->getTorrentFile()->getTotalSize() - _trackerManager->getBTTask()->getDownlaodCount());	pkg.uploaded = htonl(_trackerManager->getBTTask()->getUploadCount());	pkg.event = htonl(getCurrentEvent());	pkg.ip = htonl(0);	pkg.key = htonl(_transID * rand());	pkg.num_want = htonl(100);	pkg.port = htons(_trackerManager->getBTTask()->getAcceptor()->getPort());	pkg.extensions = 0;		sendto(getHandle(), &pkg, sizeof(pkg), 0, (const struct sockaddr*)&_serverAddr, sizeof(_serverAddr));}void CUDPTracker::processPkg(unsigned int actionID, char* data, size_t len){	LOG_DEBUG("recv pkg from UDP Tracker, actionID="<<actionID<<" len="<<len);		if(actionID == 3)	{		_state = TS_ERROR;		_stateStr.clear();		_stateStr.append((const char*)data, len);		_nextUpdateTick = GetTickCount() + 15*1000;	}		if(actionID == 0)	{		_connectionID = *((int64_t*)data);		_connectionID = ntohll(_connectionID);		_state = TS_REQUESTING;		sendAnnouncPacket();		_nextUpdateTick = GetTickCount() + 15*1000;	}		if(actionID == 1)	{		unsigned int interval = *((unsigned int*)data);		interval = htonl(interval);				unsigned int leechers = *((unsigned int*)(data+4));		leechers = htonl(leechers);				unsigned int seeders = *((unsigned int*)(data+8));		seeders = htonl(seeders);						_interval = interval;		_totalPeer = leechers + seeders;		_completePeer = seeders;		LOG_DEBUG("UDP Tracker return, interval="<<interval<<" leechers="<<leechers<<" seeders="<<seeders);				char* pbuf = NULL;		for(unsigned int i=0; i<(len-12)/6; ++i)		{			pbuf = data + 12 + i*6;						unsigned int ip = *((unsigned int*)pbuf);			unsigned short port = *((unsigned short*)(pbuf+4));			port = ntohs(port);						if(ip != 0 && port != 0)			{				char ipBuf[256];				std::string ipStr = inet_ntop(AF_INET, &ip, ipBuf, 256);								LOG_DEBUG("UDP peer, ip="<<ipStr<<" port="<<port);				_trackerManager->getBTTask()->getPeerManager()->addPeerInfoWithoutID(ipStr.c_str(), port);			}					}				_state = TS_OK;		unsigned int connectedPeerCount = _trackerManager->getBTTask()->getPeerManager()->getConnectedPeerCount();		unsigned int maxPeerLinkCount = _trackerManager->getBTTask()->getPeerLinkMax();				if(connectedPeerCount >= maxPeerLinkCount			|| (connectedPeerCount > _totalPeer/2)			|| _interval <= 2*60)		{			_nextUpdateTick = GetTickCount() + _interval*1000;		} 		else		{			_nextUpdateTick = GetTickCount() + 2*60*1000;		}				//Set some flags		if(_currentEvent == 2)		{			_startEventSend = true;		}else if(_currentEvent == 1)		{			_completeEventSend = true;		}				}}int CUDPTracker::getCurrentEvent(){	if(!_startEventSend)	{		_currentEvent = 2;		return 2;	}		if(_trackerManager->getBTTask()->getStorage()->finished()		&& _trackerManager->getBTTask()->getStorage()->getBanedCount() == 0		&& !_completeEventSend)	{		_currentEvent = 1;		return 1;	}		return 0;	}

⌨️ 快捷键说明

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