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

📄 tcptracker.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-07 20:09 */  #include <unistd.h> #include <arpa/inet.h>#include <curl/curl.h>#include <string>#include <iostream>#include "TCPTracker.h"#include "bdict.h"#include "blist.h"#include "binteger.h"#include "bstring.h"#include "log.h"#include "utils.h"size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp){		CTCPTracker* tracker = (CTCPTracker*)userp;                std::string str;        str.append((char*)buffer, size * nmemb);              tracker->addResponse(str);               return size * nmemb;}CTCPTracker::CTCPTracker(){	 _complete_peer = 0;	 _total_peer = 0;	 _interval = 0;		 _nextUpdateTick = GetTickCount();	 	_startEventSend = false;	_completeEventSend = false;	 }CTCPTracker::~CTCPTracker(){}void CTCPTracker::update(){	CURL* handle = curl_easy_init();	_tracker_response.clear();	_state = TS_CONNECTING;	_state_str = "connecting";		_currentEvent = getCurrentEvent();	std::string url = makeTrackerUrl(event2Str(_currentEvent));		curl_easy_setopt(handle, CURLOPT_URL, url.c_str());    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_data);    curl_easy_setopt(handle, CURLOPT_WRITEDATA, this);    curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1);    curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1);    curl_easy_setopt(handle, CURLOPT_TIMEOUT, 15);    CURLcode ret = curl_easy_perform(handle);        if(ret == CURLE_OK)    {    	parseResponse();    	    }    else    {    	_state = TS_ERROR;    	_state_str = curl_easy_strerror(ret);    	LOG_INFO("TCPTracker Error(curl) : "<<_state_str);    	    	_nextUpdateTick =  GetTickCount() + 60*1000;    }		curl_easy_cleanup(handle);}void CTCPTracker::stop(){}bool CTCPTracker::isProtocolSupported(const char* protocolName){	if(strcmp("http", protocolName) == 0		|| strcmp("HTTP", protocolName) == 0)	{		return true;	}		return false;}void CTCPTracker::setUrl(const char* url){	_url = url;}TTrackerState CTCPTracker::getState(){	return _state;}void CTCPTracker::addResponse(std::string content){	_tracker_response += content;}void CTCPTracker::parseResponse(){	CBDict dict;	int ret = dict.parse((const char*)_tracker_response.c_str(), _tracker_response.size());	if(ret <= 0)	{		LOG_INFO("_tracker_response parse error");		_state = TS_ERROR;		_state_str = "can not parse _tracker_responser";		_nextUpdateTick = GetTickCount() + 60*1000;				return;	}	LOG_DEBUG("tracker "<<_url);	CBString* str = (CBString*)dict.getValue("failure reason");	if(str != NULL)	{		LOG_INFO("tracker return failure reason : " << str->getValue());		_state = TS_ERROR;		_state_str = str->getValue();		_nextUpdateTick = GetTickCount() + 60*1000;		return;	}					CBInteger* interval = (CBInteger*)dict.getValue("interval");	if(interval != NULL)	{		_interval = interval->getValue();		LOG_INFO("tracker return interval : " << interval->getValue());	}	CBInteger* done = (CBInteger*)dict.getValue("done peers");	CBInteger* total = (CBInteger*)dict.getValue("num peers");	if(done != NULL && total != NULL)	{		_complete_peer = (int)done->getValue();		_total_peer = (int)total->getValue();	}		// another type extension	CBInteger* complete = (CBInteger*)dict.getValue("complete");	CBInteger* incomplete = (CBInteger*)dict.getValue("incomplete");	if(complete != NULL && incomplete != NULL)	{		_complete_peer = (int)complete->getValue();		_total_peer = 	_complete_peer + (int)incomplete->getValue();	}	LOG_INFO("tracker return _complete_peer = " << _complete_peer);	LOG_INFO("tracker return _total_peer = " << _total_peer);		// Peers	unsigned int peerCount = 0;	CBObject* peersObj = (CBList*)dict.getValue("peers");	if(peersObj != NULL		&& peersObj->getType() == 3)	{		CBList* peers = (CBList*)peersObj;		peerCount = peers->getCount();				//LOG_INFO("tracker return " << count << " peers ");				for(unsigned int i=0; i<peerCount; ++i)		{			CBDict* peer = (CBDict*)peers->getValue(i);						//CBString* id = (CBString*)peer->getValue("peer id");			//LOG_DEBUG("peer id = " << id->getValue());						CBString* ip = (CBString*)peer->getValue("ip");			//LOG_DEBUG("ip = "<<ip->getValue());						CBInteger* port = (CBInteger*)peer->getValue("port");			//LOG_DEBUG("port = "<<port->getValue());								_trackerManager->getBTTask()->getPeerManager()->addPeerInfoWithoutID(ip->getValue().c_str(), port->getValue());		}	}		if(peersObj != NULL		&& peersObj->getType() == 2)	{		CBString* peers = (CBString*)peersObj;				std::string peerStr = peers->getValue();		if(peerStr.size() % 6 == 0)		{			for(unsigned int i=0; i<peerStr.size()/6; ++i)			{				unsigned int ip =*( (unsigned int*)(peerStr.data()+i*6));				unsigned short port =*( (unsigned short*)(peerStr.data()+i*6+4));				port = ntohs(port);								char ipBuf[256];				std::string ipStr = inet_ntop(AF_INET, &ip, ipBuf, 256);				_trackerManager->getBTTask()->getPeerManager()->addPeerInfoWithoutID(ipStr.c_str(), port);			}		}				LOG_DEBUG("compact model");			}		//set _nextUpdateTick	_state = TS_OK;	unsigned int connectedPeerCount = _trackerManager->getBTTask()->getPeerManager()->getConnectedPeerCount();	unsigned int maxPeerLinkCount = _trackerManager->getBTTask()->getPeerLinkMax();		if(connectedPeerCount >= maxPeerLinkCount		|| (connectedPeerCount > _total_peer/2)		|| _interval <= 2*60)	{		_nextUpdateTick = GetTickCount() + _interval*1000;	} 	else	{		_nextUpdateTick = GetTickCount() + 2*60*1000;	}		//Set some flags	if(_currentEvent == TE_START)	{		_startEventSend = true;	}else if(_currentEvent == TE_COMPLETE)	{		_completeEventSend = true;	}	}std::string CTCPTracker::makeTrackerUrl(const char* event){/*	std::string result = str(boost::format("%1%?info_hash=%2%&peer_id=%3%&port=%4%&uploaded=%5%&downloaded=%6%&left=%7%&event=%8%")		% _url		% urlEncode(_trackerManager->getBTTask()->getTorrentFile()->getInfoHash(), 20)		% urlEncode((const unsigned char*)(_trackerManager->getBTTask()->getPeerID().c_str()), 20)		% _trackerManager->getBTTask()->getAcceptor()->getPort()		% _trackerManager->getBTTask()->getDownlaodCount()		% _trackerManager->getBTTask()->getUploadCount()		% _trackerManager->getBTTask()->getStorage()->getLeftCount()		% event);*/				LOG_DEBUG("event="<<event);		char result[1024];		sprintf(result, "%s?info_hash=%s&peer_id=%s&port=%u&compact=1&uploaded=%llu&downloaded=%llu&left=%llu&event=%s",			_url.c_str(),			urlEncode(_trackerManager->getBTTask()->getTorrentFile()->getInfoHash(), 20).c_str(),			urlEncode((const unsigned char*)(_trackerManager->getBTTask()->getPeerID().c_str()), 20).c_str(),			_trackerManager->getBTTask()->getAcceptor()->getPort(),			_trackerManager->getBTTask()->getDownlaodCount(),			_trackerManager->getBTTask()->getUploadCount(),			_trackerManager->getBTTask()->getStorage()->getLeftCount(),			event);				LOG_DEBUG("TrackerUrl = " << result);				return result;		}const std::string& CTCPTracker::getStateStr(){	return _state_str;}unsigned int CTCPTracker::getSeedCount(){	return _complete_peer;}unsigned int CTCPTracker::getPeerCount(){	return _total_peer;}unsigned int CTCPTracker::getInterval(){	return _interval;}void CTCPTracker::setTrackerManager(ITrackerManager* trackerManager){	_trackerManager = trackerManager;}TTrackerEvent  CTCPTracker::getCurrentEvent(){	if(!_startEventSend)	{		return TE_START;	}		if(_trackerManager->getBTTask()->getStorage()->finished()		&& _trackerManager->getBTTask()->getStorage()->getBanedCount() == 0		&& !_completeEventSend)	{		return TE_COMPLETE;	}		return TE_NONE;}const char* CTCPTracker::event2Str(TTrackerEvent event){	switch(event)	{		case TE_START :			return "started";		case TE_STOP :			return "stopped";		case TE_COMPLETE :			return "completed";		case TE_NONE :			return "";		}			return "";}unsigned int CTCPTracker::getNextUpdateTick(){	return _nextUpdateTick;}

⌨️ 快捷键说明

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