一个简单的BitTorrent客户端实现(五):tracker manager和tracker实现
2016-04-21 16:00
288 查看
关于tracker和tracker manager
tracker在整个bt协议中起着很重要的作用,从tracker那里我们可以获取当前正在下载的peer列表,从而与它们交互,进行文件的上传和下载。TrackerManager顾名思义就是管理tracker的。因为可能有多个tracker,所以采用了trackermanager进行管理,所以也显得比较有条理些。tracker类的实现
本程序中只实现了TCP tracker,UDP tracker一直苦于没有找到可供测试的torrent文件。所以没实现。tracker类负责与服务器进行交互,获取正在下载的peer列表,主要实现在update函数中。void CTCPTracker::Update() { CURL *pHandle = curl_easy_init(); m_strTrackerResponse.clear(); m_nTrackerState = TS_CONNECTING; m_nCurrentEvent = GetCurrentEvent(); string strURL = GenTrackerURL(Event2Str(m_nCurrentEvent)); curl_easy_setopt(pHandle, CURLOPT_URL, strURL.c_str()); curl_easy_setopt(pHandle, CURLOPT_WRITEFUNCTION, OnRecvData); curl_easy_setopt(pHandle, CURLOPT_WRITEDATA, this); curl_easy_setopt(pHandle, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(pHandle, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(pHandle, CURLOPT_TIMEOUT, 60); CURLcode nRetCode = curl_easy_perform(pHandle); if (nRetCode == CURLE_OK) { ParseTrackerResponse(); } else { m_nTrackerState = TS_ERROR; m_llNextUpdateTick = GetTickCount() + 15 * 1000; } curl_easy_cleanup(pHandle); }
之前使用纯socket编程连接tracker服务器,发行总是连不上,所以改用libcurl,这个东西确实太方便了。用起来太舒服了。关于libcurl,这里就不作介绍了。
TrackerManager实现
trackermanager主要做了以下两件重要的事情:(1)根据种子文件中的tracker列表创建tracker。
void CTrackerManager::CreateTrackers() { vector<string> vecAnnouce = m_pTorrentTask->GetTorrentFile()->GetAnnounceList(); vector<string>::iterator it = vecAnnouce.begin(); for (; it != vecAnnouce.end(); ++it) { ITracker *pTracker = NULL; int nStart = 0; int nEnd = 0; if (CTorrentParser::FindPattern((*it).c_str(), "HTTP:", nStart, nEnd) == true || CTorrentParser::FindPattern((*it).c_str(), "http:", nStart, nEnd) == true) { pTracker = new CTCPTracker; } if (pTracker != NULL) { pTracker->SetURL((*it).c_str()); pTracker->SetTrackerManager(this); m_vecTrackers.push_back(pTracker); } } }
目前这里只处理了http类型的tracker,采用正则表达式来提取tracker信息。以后会继续完善。
(2)在一个线程中,让tracker各自的更新,拉取最新的peer列表。
void CTrackerManager::Svc() { while(!m_bExit) { vector<ITracker *>::iterator it = m_vecTrackers.begin(); for (; it != m_vecTrackers.end(); ++it) { if (m_bExit) { break; } if (GetTickCount() < (*it)->GetNextUpdateTick()) { continue; } (*it)->Update(); } usleep(150000); } }
里面最重要的就是各个tracker的Update。
相关文章推荐
- SQL语句妙用
- 二叉树的遍历 Java版
- 使用GoAccess分析Nginx日志以及sed/awk手动分析实践
- 关于block使用导致键盘的延时操作
- 控制 psql 的时间戳timestamp精度
- live555学习笔记-RTSPClient分析
- QT Creator Beautifying Source Code with Artistic Style
- Android学习资料整理(二)
- 自定义序列顺序思想 Permutations
- 基于 OSG OpenSceneGraph HTC Vive 的实现
- Visual Studio:error MSB8020
- mysql 日期格式都是带百分号的,======如下
- js keyup、keypress和keydown事件 详解
- cocos2dx 图片模糊
- leetcode15.3Sum
- \0 的ASCII码值是多少
- 添加以及删除className
- Python下进程与线程的原理及区别
- C++之输入(cin)详解
- java LinkedList实现原理概述