我在大四上学期时曾做过BT客户端的移植工作当时程序有Word下载.docx
《我在大四上学期时曾做过BT客户端的移植工作当时程序有Word下载.docx》由会员分享,可在线阅读,更多相关《我在大四上学期时曾做过BT客户端的移植工作当时程序有Word下载.docx(10页珍藏版)》请在冰豆网上搜索。
有关BT协议的论述主要有三篇文章:
1,BT官方网站上的协议解释:
http:
//www.bittorrent.org/protocol.html。
2,Bittorrent
Protocol
Specification,http:
//wiki.theory.org/BitTorrentSpecification。
3,Incentives
Build
Robustness
in
BitTorrent,
这三篇文章从不同方面给出了BT协议从算法到实现的一个较为简略的描述。
为了更深入地理解BT协议,自己动手写一个BT客户端或阅读一个BT客户端的源代码的工作是必不可少的。
1.2
客户端的选择
Bram
Cohen是BT协议的创建者。
根据这份协议,他写了BT的第一个客户端,也就是BitTorrent公司的产品:
BitTorrent。
可以说,
BitTorrent的源码和BT协议是门当户对,要理解协议,先从BitTorrent的源码开始是最好不过的了。
但Bram
Cohen是用Python语言写的BitTorrent,这给很多不懂Python的人(我也在内)带来了很多麻烦:
为了看懂一份源码而去新学一份计算机编程语言是不是有些不值得呢?
好在BT客户端是如此之多,我们有很大的选择空间。
除了Python,还有Java(主要是Azureus,国外非常流行的多平台的客户端)和C++(其它大部分客户端)写成的程序。
经过多方比较,我选择了CTorrent这个客户端。
虽然CTorrent是用C++写成的,但仅仅算是一个轻量级(light-
weighted)的C++软件。
它的库函数依赖型很小,只用到了Open
SSL库用来计算哈希值,所以可以工作在Linux,
FreeBSD和MacOS平台。
CTorrent没有图形界面,工作在命令行模式。
另外,libtorrent(
1.3
CTorrent简介
CTorrent是由YuHong写的一个BT客户端。
它的代码大部分都可以看作是C代码,只是用到了C++的类概念,还有一小部分构造函数,析构函数,函数和操作符重载的代码。
不懂C++的人只需有一些C++的基本知识就完全能看懂源代码了。
CTorrent的主页是,它遵循GPL。
作者在CTorrent主页上称自己为YuHong,这里有一篇他写完CTorrent后发的帖子:
//www.freebsdchina.org/forum/viewtopic.php?
p=39082,想必是中国人吧。
用户在使用时发现CTorrent有一些bug,一个比较明显的例子是CTorrent下载完成后不会立即把缓存中的数据写入硬盘,这样如果按下
Ctrl-C结束程序的话会造成数据的不完整。
CTorrent的最新版本是1.3.4(2004年9月7日发布),作者后面就没有再发布新版本,软件的
一些问题也没有得到修正。
虽然有一些bug,但得益于CTorrent是开源项目,很快就有人为CTorrent写了一些补丁(
Holmes的人贡献颇多,他为CTorrent打了很多patch,然后重新发布,取名为Enhanced
CTorrent。
Enhanced
CTorrent的主页是
Holmes用Perl写的一个CTorrent
Control
Server,可以实现对Enhanced
CTorrent运行状况的监控。
这篇CTorrent的源码分析是基于ctorrent-dhn1.2版本的,原因是由于我查看Enhanced
CTorrent较早,那时还没有ctorrent-dhn2版本,再加上自己偷懒,没有赶在ctorrent-dhn2发布之前把文章写完……比较而
言,dnh1.2版本已经是一个相对稳定的版本了,dnh2的改进主要是在性能方面,而非bug
fix(容我再强词夺理一句,我简略看过dnh2版本的代码,在dnh1.2的基础上,看懂dnh2是没有问题的)。
另外,Dennis
Holmes虽然重新发布了CTorrent,但他本人对原作者是极为尊敬的。
在他的dnh版本中,原封不动地保留了原先代码的痕迹,自己的改动也加上了
相应的注释。
虽然CTorrent有一些bug,但正如Dennis
Holmes所言:
谁又说其它客户端没有bug呢?
我的这篇源码分析也统一称CTorrent和Enhanced
CTorrent为CTorrent,只有在需要两个版本比较时才区分开来。
2.
准备工作
2.1
知识储备
要看懂CTorrent源码和本篇源码分析,读者需要具备如下知识:
1,前面列举的BT协议的大致了解。
2,网络socket编程方面的基本知识,主要是select()函数的使用。
3,至少会C语言,了解C++的基本使用方法(主要是类,构造函数,析构函数和重载)。
2.2
我对本篇源码分析的说明
1,
源代码中如果出现一些乱码(特别是在终端中查看时),设置:
$export
LANG=C
即可看到原作者写的中文注释。
2,
源码解说一般采取流程图的形式,有一些函数的具体功能不是很集中,画流程图也表示不出前后联系来,就直接写了步骤分析。
有些源码比较晦涩的,会直接分析源代码。
3,
源代码中的全部变量都有分析。
大部分函数都有说明,少数特别简单的函数和见名知意的函数没有说明。
4,
源代码中看似简单的表述实际蕴含着及其严格的操作要求(例如宏P_HANDSHAKE的意思是可以进行握手通信了,而不是正在进行握手通信或者已经完成握手通信了)。
所以必须正确理解源代码各个宏,变量,函数的确切含义,才能真正理解程序的流程和作用。
5,
分析源码的最终目的是彻底理解BT协议的实现结构,以及BT通信性能卓越的原因。
虽然程序中涉及BT协议算法的只有几个函数,但这几个函数是在其它大量代
码的基础上构建的。
一些有关种子文件的制作和解析的代码虽然看似和BT通信关系不大,但若前面的基础没有理解正确,会给后面的算法分析带来很大的麻烦。
6,
原作者的C语言技巧相当高,enjoy
it!
7,
本文中“函数”指的是当前正在分析的函数,而“程序”指的是整个CTorrent程序。
8,
本文中“消息”指的是peer发来的固定格式的消息,例如piece消息,bitfield消息等。
“数据”指的是客户端要下载的东西,例如一个游戏,一段视频等。
9,
英文中种子文件有很多说法,如.torrent
file,
metainfo
file,本文中均用它们的中文名:
种子文件。
10,英文中关于BT协议的最小数据单元有很多说法,如slice,block,subpiece,本文中使用CTorrent源代码中的说法:
slice。
3.
总述
3.1
CTorrent的命令行参数的意义
-h/-H:
显示帮助命令
-x:
只解码并显示种子文件信息,不下载。
-c:
只检查已下载的数据,不下载。
-v:
打开debug调试输出。
下载选项:
-e
int
下载完毕后的做种时间(单位:
小时),默认为72小时。
-p
port
绑定端口,默认为2706。
-s
save_as
重命名下载的文件,若是下载的是多个文件,则sava_as是包含多文件的目录。
-C
cache_size
缓存大小,默认为16MB。
-f
强制做种模式,不进行SHA1
HASH检查。
-b
bf_filename
piece位图文件名,详见BitField:
:
SetReferFile()。
-M
max_peers
客户端最多与多少个peer通信。
-m
min_peers
客户端至少与多少个peer通信。
-n
file_number
多文件下,选择哪个文件去下载(例如第二个文件file_number就为2)。
-D
rate
限制最大下载速率(单位:
KB/s)。
-U
限制最大上传速率(单位:
-P
peer_id
客户端通信的ID,默认为-CD0102-。
下载数据文件示例:
ctorrent
new_filename
12
32
6881
eg.torrent
制作种子文件示例:
-t
file_to_make.avi
a.torrent
-u
protocol:
//address/announce
3.2
CTorrent的状态栏的意义
CTorrent运行时输出格式如下:
$
/
1/10/40
[3/148/148]
2MB,1MB
|
48,20K/s
80,40K
E:
0,1
各项意义为:
/:
表明客户端正在工作的符号,以”-
\
/”循环。
1:
种子数目。
10:
客户端正在通信的非种子的peer数目。
40:
tracker服务器知道的peer数,也是整个bt通信群的peer数。
3:
客户端已经下载的piece数目。
148:
数据文件全部的piece数目。
客户端可以得到的piece数目,若此数小于全部piece数目则不会下载到完整的数据。
2MB