一个简单的BitTorrent客户端实现(二):种子文件解析及信息保存

关于种子文件

BT的种子文件一般是以.torrent作为后缀的。关于种子文件的编码,这里不再做任何介绍。本程序采用的测试种子文件为ubuntu-14.04.3-desktop-i386.torrent,各位可以到http://mirrors.163.com/ubuntu-releases/14.04.3/去下载,当然也可以使用别的种子文件。我们用notepad++打开该文件,可以看到有如下内容:

d8:announce39:http://torrent.ubuntu.com:6969/announce13:announce-listll39:http://torrent.ubuntu.com:6969/announceel44:http://ipv6.torrent.ubuntu.com:6969/announceee7:comment29:Ubuntu CD releases.ubuntu.com13:creation datei1438887077e4:infod6:lengthi1064304640e4:name31:ubuntu-14.04.3-desktop-i386.iso12:piece lengthi524288e6:pieces40600:瓋x廥真傲豴節`?衿?j?篹畔bY?D钷緁鍗澛!惌bX$賌m?楐?釳K1厘?岺珮禉?勺?u?j@?I0V瀏r騿屷濏D堎&甃?鼆s珥|烞男把岮K砨维当O屪諐綣廌跡籢纆蔢湓g5
m€酟?踸抙遍琅_  婰戢?ヤk矂尛?p迳cI鞱@濦?

本文的目的旨在正确解析种子文件。

如何解析种子文件

解析种子文件,这里采用的是正则表达式的方式来实现。大家也可以用别的方式。这里使用的正则表达式库是DEELX,源代码在deelx.h中。解析种子文件的类为CTorrentParser。里面有个静态函数用于在一段文本中查找指定的模式,函数名为FindPattern,下面是它的实现代码:

bool CTorrentParser::FindPattern( const char *pContent, const char *pPattern, int &nStart, int &nEnd )
{
    CRegexpT<char> Regexp(pPattern);
    MatchResult clResult = Regexp.Match(pContent);
    bool bFind = false;

    if (clResult.IsMatched())
    {
        nStart = clResult.GetStart();
        nEnd = clResult.GetEnd();

        bFind = true;
    }

    return bFind;
}

以获取种子文件中的announce为例,我们可以写出如下的代码:

bool CTorrentParser::GetMainAnnounce( string &strAnnounce )
{
    int nStart = 0;
    int nEnd = 0;
    bool bFind = false;

    if (FindPattern(m_lpContent, "8:announce", nStart, nEnd) == true)
    {
        const char* pContent = m_lpContent + nEnd;
        if (FindPattern(pContent, "[1-9]+[0-9]{0,}:", nStart, nEnd) == true)
        {
            strAnnounce.assign(pContent + nEnd, atol(pContent + nStart));
            bFind = true;
        }
    }

    return bFind;
}

保存种子文件信息

解析完了种子文件信息,我们需要保存,在该程序中信息保存在CTorrentFile类中。Load函数实现了该功能:

void CTorrentFile::Load(const char *pFilePath)
{
    m_strTorrentFilePath.assign(pFilePath);
    CTorrentParser clParser;
    clParser.LoadTorrentFile(pFilePath);
    bool bFind = clParser.GetMainAnnounce(m_strMainAnnounce);
    clParser.GetAnnounceList(m_vecAnnounceList);
    clParser.GetFileList(m_vecFileList);
    m_bMultiFiles = clParser.IsMultiFiles();
    clParser.GetPieceLength(m_nPieceLength);
    clParser.GetPiecesHash(m_strPiecesHash);
    clParser.GetName(m_strName);
    clParser.GetComment(m_strComment);
    clParser.GetCreatedBy(m_strCreatedBy);
    clParser.GetCreationDate(m_strCreationDate);
    clParser.GetInfoHash(m_szInfoHash);

    if (bFind)
    {
        if (find(m_vecAnnounceList.begin(), m_vecAnnounceList.end(),
                m_strMainAnnounce) == m_vecAnnounceList.end())
        {
            m_vecAnnounceList.push_back(m_strMainAnnounce);
        }
    }
}

总结

关于种子文件解析和保存,就简单的介绍到这里,解析种子文件只是其中很小的一部分,也是很简单的。真正麻烦的东西在后头。
程序源代码下载地址:http://download.csdn.net/detail/zxywd/9415711

你可能感兴趣的:(一个简单的BitTorrent客户端实现(二):种子文件解析及信息保存)