一个简单的BitTorrent客户端实现(五):tracker manager和tracker实现

关于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。
程序源代码下载地址:http://download.csdn.net/detail/zxywd/9415711

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值