《最新BT协议分析文档(new).doc》由会员分享,可在线阅读,更多相关《最新BT协议分析文档(new).doc(67页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.-author-dateBT协议分析文档(new)BitTorrent协议分析文档BitTorrent协议分析文档1 协议相关概念1.1 简介BitTorrent协议(简称BT,俗称比特洪流、BT下载)是一个网络文件传输协议,它能够实现点对点文件分享的技术。比起其他点对点的协议,它更有多点对多点的特性,这个特点简单的说就是:下载的人越多,速度越快。下载完不去马上关闭BitTorrent软件,
2、就可以成为种子(拥有完整的文件者)分享让其他人下载。1.2 原理普通的HTTP/FTP下载使用TCP/IP协议,BitTorrent协议是架构于TCP/IP协议之上的一个P2P文件传输协议,处于TCP/IP结构的应用层。 BitTorrent协议本身也包含了很多具体的内容协议和扩展协议,并在不断扩充中。根据BitTorrent协议,文件发布者会根据要发布的文件生成提供一个.torrent文件,即种子文件,也简称为“种子”。.torrent文件本质上是文本文件,包含Tracker信息和文件信息两部分。Tracker信息主要是BT下载中需要用到的Tracker服务器的地址和针对Tracker服务器
3、的设置,文件信息是根据对目标文件的计算生成的,计算结果根据BitTorrent协议内的B编码规则进行编码。它的主要原理是需要把提供下载的文件虚拟分成大小相等的块,块大小必须为2k的整数次方(由于是虚拟分块,硬盘上并不产生各个块文件),并把每个块的索引信息和Hash验证码写入.torrent文件中;所以,.torrent文件就是被下载文件的“索引”。下载者要下载文件内容,需要先得到相应的.torrent文件,然后使用BT客户端软件进行下载。下载时,BT客户端首先解析.torrent文件得到Tracker地址,然后连接Tracker服务器。Tracker服务器回应下载者的请求, 提供下载者其他下载
4、者(包括发布者)的IP。下载者再连接其他下载者,根据.torrent文件,两者分别对方告知自己已经有的块,然后交换对方没有的数 据。此时不需要其他服务器参与,分散了单个线路上的数据流量,因此减轻了服务器负担。下载者每得到一个块,需要算出下载块的Hash验证码与.torrent文件中的对比,如果一样则说明块正确,不一样则需要重新下载这个块。这种规定是为了解决下载内容准确性的问题。一般的HTTP/FTP下载,发布文件仅在某个或某几个服务器,下载的人太多,服务器的带宽很易不胜负荷,变得很慢。而BitTorrent协议下载的特点是,下载的人越多,提供的带宽也越多,种子也会越来越多,下载速度就越快。而有
5、些人下载完成后关掉下载任务,提供较少量数据给其他用户,为尽量避免这种行为,在非官方BitTorrent协议中存在超级种子(super seed)的算法。这种算法允许文件发布者分几步发布文件,发布者不需要一次提供文件所有内容,而是慢慢开放的下载内容的比例,延长下载时间。此时,速度快的人由于未下载完必须提供给他人数据,速度慢的人有更多机会得到数据。1.3 相关概念Tracker:收集下载者信息的服务器,并将此信息提供给其他下载者,使下载者们相互连接起来,传输数据。种子:指一个下载任务中所有文件都被某下载者完整的下载,此时下载者成为一个种子。发布者本身发布的文件就是原始种子。也指.torrent文件
6、。做种:发布者提供下载任务的全部内容的行为;下载者下载完成后继续提供给他人下载的行为。DHT网络:DHT全称为分布式哈希表(Distributed Hash Table),是一种分布式存储方法。在不需要服务器的情况下,每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整个DHT网络的寻址和存储。使用支持该技术的BT下载软件,用户无需连上Tracker就可以下载,因为软件会在DHT网络中寻找下载同一文件的其他用户并与之通讯,开始下载任务。有些软件(如比特精灵)还会自动通过DHT搜索种子资源,构成种子市场。另外,这里使用的DHT算法叫Kademlia(在eMule中也有使用,称为KA
7、D,具体实现协议有所不同)。这种技术好处十分明显,就是大大减轻了Tracker的负担(甚至不需要)。用户之间可以更快速建立通讯(特别是与Tracker连接不上的时候)。2 交互流程为了部署 BT,首先需要将一个扩展名为 .torrent 的文件放在一个普通的web服务器上。.torrent文件包含了要共享的文件的信息,包括文件名、大小、文件的散列信息和一个指向tracker的 url。Tracker负责帮助下载者能够获取其它下载者的信息。Tracker和下载者之间使用一种很简单的基于HTTP的协议进行交互,下载者告诉 tracker自己要下载的文件、自己使用的端口以及类似的信息,tracker
8、告诉下载者其它下载同样文件的下载者的联系信息。下载者利用这些信息相互之间建立连接。一个被成为“种子”的下载者,必须首先被启动,它知道完整的文件信息。对tracker和web服务器的带宽需求很低,而种子必须至少发送原始文件的一份完整拷贝。P2P的核心思想就是没有服务器的概念,任何一个下载者既是client,又是server。下载者从别人那里取文件的时候,称为下载,而为别人提供文件的时候,称为上载(传)。为了完成一次部署,至少需要一个 tracker和一个seed。所谓tracker,是一个服务器,负责帮助peers之间相互建立连接。而seed,通常是第一个向tracker注册,然后它就开始进入循
9、环,等待为别人提供文件,也就是说,第一个seed只负责上传文件。一旦有一个peer向tracker注册后,就可以取得 seed的信息,从而与seed建立连接。从seed处读取文件。由于原始的文件,只有seed拥有,所有说,seed至少要上传原始文件的一份完整拷贝。如果又有一个peer加入进来,那么它可以同时和seed和前一个peer建立连接,然后从这两者处获取文件。3 协议详解3.1. 种子文件种子文件(以 .torrent 结尾的文件)的内容是一个编码的字典,包含以下列表中的各项。所有字符串值都以 UTF-8 编码。标记没有为“可选”的键值是必需的字段: 表1 种子文件内容列表字段属性描述i
10、nfo必须一个描述 torrent 文件的字典。有两种可能的形式:一种是没有目录结构的“单一文件”,另一种是包含子目录树的“多文件”announce必须服务器的发布URL (字符串)announce-list可选发布列表,这是官方规范的一个扩展,它是向后兼容的。此键值用来执行备份服务器的列表。完整的规范可在 找到。creation date可选torrent 文件的创建时间,使用标准 Unix 时间格式(从 UTC 1970年1月1日 00:00:00 开始,整数秒)comment可选创建 torrent 文件的名字和程序版本(字符串)对于“单一文件”来说,信息字典包含以下的结构:length
11、: 文件字节数长度(整数)md5sum: (可选)一个 32 位的 16 进制字符串,它对应于文件的 MD5和。不被 BitTorrent 所使用,但被一些程序包含,以提供更大的兼容性。name: 文件的名称。建议使用(字节串)。piece length: 每个片断的字节数(整数)。pieces: 包含所有 20 字节 SHA-1 散列值的字符串,每个片断都有唯一的值。(字节串)对于“多文件”来说,信息字典包含以下的结构:name: 结构中根目录的名称包含上述文件列表中所有文件的目录(字符串)piece length: 每个片断的字节数(整数)。pieces: 包含所有 20 字节 SHA-1
12、 散列值的字符串,每个片断都有唯一的值。(字节串)files: 字典列表,每个文件都有一个。每个在表中的字典包含以下内容:length:文件长度的字节数(整数)md5sum:(可选)一个 32 位的 16 进制字符串,它对应于文件的 MD5和。不被 BitTorrent 所使用,但被一些程序包含,以提供更大的兼容性。path:一个包含着一个或多个字符串元素的,它包含路径和文件名。每个表中元素对应于一个目录名或(在最后的元素的情况下)文件名。例:文件名“dir1/dir2/file.ext”将包含三种串元素:“dir1”、“dir2”和“file.ext”。编码为串表的例子“l4:dir14:d
13、ir28:file.exte”需要注意的是,piece length指定了标准的片断大小,通常是 2 的 n 次方。片断长度的一般是根据 torrent 文件中所有数据的数量来决定的,如果片断太大,会导致效率低,出错概率增加;而如果太小,则会使生成的 torrent 元数据文件过大。常识决定使用最小的片断大小,这样就会使生成的 torrent 文件不大于 5075 KB (可以减轻存储 torrent 文件服务器的负担)。但是,由于没有严格限制存储和带宽,即使为了高效率的共享文件可能导致生成更大的 torrent 文件,也建议将小于 810 GB 文件的片断大小设为小于或等于 512 KB。通
14、常大小是 256 KB,512 KB 和 1 MB。除了最后的片断大小不定以外,其余片断大小是相等的。因此片断的数目由总大小决定。对于多文件模式下的片断边界,将文件数据设想为一个长的连续流, 由文件有序列表中的每个文件相互连接而成。片断数目和其边界的决定方式与单一文件相同。片断可能由两个文件的边界组成。还有,每个piece都有相应的 SHA-1 hash 数据校验码。这些校验码相互连接形成上述的信息字典的片断值(pieces)。注意这不是一个表,而是一个字符串。其长度必须是 20 字节的整数倍。3.2. Tracker HTTP/HTTPS 协议Tracker是用来响应 HTTP GET 请求
15、的一种 HTTP/HTTPS 服务。该请求包括客户端的度量标准,这个标准可以帮助服务器全面统计 torrent 文件。基本的 URL 包括元数据文件(torrent)中定义的“发布 URL”。再将那些参数通过标准 CGI 方法添加到此 URL 中(如:“?”在发布 URL 之后,紧接着“参数=值”的序列,分隔符“&”)注意所有在 URL 中的二进制数据(特别是 info_hash 和 peer_id)必须使用转义符。这意味着除 0-9,a-z,A-Z和$-_.+!*()外,其余字节需要采用“%nn”格式的编码,其中的“nn”是字节的 16 进制数值。(详细见 RFC1738)3.2.1 客户端
16、向服务器的 GET 请求的参数如下:客户端向服务器的 GET 请求的参数如下:info_hash:种子文件中 20 字节的 SHA-1 散列值。注意此值会进入编码字典中,如上述的信息关键字的定义所述。与不需编码的 peer_id 相比,它总是被 URL 编码。peer_id:客户端 ID ,客户端用来唯一标识自己 ID 的 20 字节的串,它在客户端启动时生成。允许为任何值,包括二进制数据。目前没有特定的算法来生成客户端 ID。但是,人们会认为它至少对于自己的本地机器是唯一的,从而应该像进程 ID 一样合并数据,也可能在启动时由时标记录。见本区域下面的一般客户端编码的 peer_id。port
17、(端口):客户端监听的端口号。BitTorrent 所使用的典型端口是 6881-6889。如果此范围的端口都无效,可以选择其他的。uploaded(已上传的):从客户端发送“已开始”事件到服务器算起的上传总量,数值采用 10 进制的 ASCII。对于没有在官方规范明确指出的,该值应为已上传的字节总数。downloaded(已下载的):从客户端发送“已开始”事件到服务器算起的下载总量,数值采用 10 进制的 ASCII。对于没有在官方规范明确指出的,该值应为已下载的字节总数。left(剩下的):客户端需要下载的字节数,以 10 进制 ASCII 编码。compact(紧密的):客户端接受一个紧
18、密的响应。客户端列表由客户端串代替,此串中每个客户端都编码成 6 字节。前 4 字节是主机名(以网络的字节顺序),后两个字节是端口号(同样以网络字节的顺序)。event(事件):如果被指定,则是started, completed, stopped,(已开始,已完成,已停止,具体含义如下)中的一个,或者为空(表示未指定)。如果未指定,此请求为常规时间间隔中的一次交互。 started(已开始):向服务器发送的第一个请求,必须包含开始值的事件关键字。 stopped(已停止):如果客户端关机则须发送到服务器上。 completed(已完成):完成下载时必须发送到服务器上。但是,当客户端启动时下载
19、完成度为 100% (即:做种中)则不会发送。可能这是允许服务器增加“已完成下载”的方法。ip:可选。客户端的真实 IP 地址,以点分四元组格式或 RFC3513 中定义的 16 进制 IPv6 地址。注意:大体上此参数没有客户端地址重要,它能由 IP 地址决定,HTTP 请求也来自该处。仅在请求参与的 IP 地址不是客户端的 IP 地址的情况下才需要。这种情况发生在客户端通过代理服务器与服务器进行通信的情形。当客户端和服务器同时处在本地 NAT 网关时也需要。原因是服务器会发出客户端的内部地址(RFC1918),这是不可到达的。所以客户端必须清楚地把自己的外部可到达的 IP 地址发送到其他客
20、户端中。不同的服务器对此参数的解释有所不同。某些只有当请求参与的 IP 地址属于 RFC1918 时才允许。有些无条件允许,但有些则完全忽略。如果使用 IPv6 地址(如:2001:db8:1:2:100),则表示客户端能通过 IPv6 进行通信。numwant(需求数目):可选。客户端想从服务器接收的用户数目。允许此值为“0”。如果不用此项,则默认值为 50 个用户。key关键字:可选。一个不与任何用户共享的另外的标识。当 IP 地址改变后,允许客户端证明它们的标识。trackerid:可选。如果先前发布包含tracker的 id,它应放在这里。no_peer_id(可选):可选。其值为1,
21、表示不需要其它用户的peer_id信息。一个实际的数据包如下图所示:图 1 客户端对Tracker的请求上图是HTTP协议的负载部分,其中的URL中包含着我们前面介绍过的各字段及其对应信息。该URL为/announce?info_hash=%ca%2b%5cNT%f6%b0%c9%00%c7%0bq%9d%29A4%f3%bc%99%cb&peer_id=M6-0-0-%8b%92%22%dag%8a%8a%96%aa%16%c9h&port=53779&uploaded=0&downloaded=0&left=100887162&key=A8FD6ACC&numwant=200&compac
22、t=1&no_peer_id=1所以,对应的其“info_hash=”之后的字符串为前面提到的种子文件中 20 字节的 SHA-1 散列值。但是这里这个值是经过编码的,比如%ca%2b%5c代表16进制0xca2b5c。“&”是分隔符,之后的peer_id=M6-0-0-%8b%92%22%dag%8a%8a%96%aa%16%c9h即为客户端用来唯一标识自己 ID 的 20 字节的串,它采用了同样的编码。我们还可以得到port=53779 :端口是53779uploaded=0 :上传了0字节downloaded=0:下载了0字节left=100887162:还剩下100887162字节ke
23、y=A8FD6ACC:客户端标识为A8FD6ACCnumwant=200:客户端想从服务器接收的用户数目为200compact=1:客户端接受一个紧密的响应no_peer_id=1:不需要其它用户的peer_id信息3.2.2 tracker的响应服务器作出“text/plain”文档的响应包括以下编码字典的关键字:failure reason(失败原因):如果当前使用此值,则其余关键字不会使用。该值是可读的错误消息,包括请求失败的原因。(字符串)warning message(警告消息):(新,可选)与失败原因相似,但响应仍然会被正常处理。警告消息看起来像错误。interval(时间间隔):
24、以秒计算,是客户端发送定期请求到服务器之后等待的时间。(强制)min interval(最小时间间隔):最小发布时间间隔。当前客户重发间隔不能小于此值。tracker id:一个客户端应在下一个通告发回的字符串。如果没有该值,先前通告会发出一个trackerid,不要丢弃旧的值,一直使用它。complete(完成):拥有完整文件的用户数,即做种者(整数)incomplete(未完成):非种子用户的数目,也叫“吸血者”(整数)注:以上2项有时候为done peers :下载完毕的节点个数num peers :当前下载的节点个数peers(用户):这个字段在字典模式(dictionary mode
25、l)下是字典的列表,每个值都有如下的关键字: peer id(用户 id):用户的自选择 ID,如上述用来发送服务器请求的(字符串) ip:用户的 IP 地址(IPv4 或 IPv6 格式)或域名(字符串) port(端口):用户的端口号(整数)peers在二进制模式(binary model)下,其值是一个6个字节的串,其中前4个字节是ip,后2个字节是端口号(都采用网络字节序也就是大字节序)。注意此响应有三层字典嵌套。例如:d5:filesd20:.d8:completei5e10:downloadedi50e10:incompletei10eeee其中“.”是 20 字节的 info_h
26、ash,以上表明有 5 个做种者,10 个吸血者和 50 个完成下载的用户。一个真实的数据包如下所示图 2 Tracker 响应上图中,“10:done peersi5e”表示5个完成用户;“8:intervali1800e”表示间隔时间是1800秒;“9:num peersi6e”表示有6个peer;“5:peers36:.”表示用户的ip和端口信息,注意到6个字节表示一个用户的信息,6个用户,6*6正好是36个字节。如上所述,用户(peers)列表长度默认值为 50。如果连接的用户少于该值,列表会更小。另外,服务器随机选择用户及其响应。服务器在响应请求时可能使用一个更智能的机构来选择用户。
27、例如,应避免向其他做种者报告种子。在事件发生(即:已停止或已完成)或客户端需要连接更多的用户时,客户端向服务器发送请求的间隔可以低于指定的时间间隔。但是,为了获得更多的用户而向服务器频繁地请求会被认为是错误的行为。如果客户端想在回应中得到许多用户,则需要在“需求数目”参数中设定。使用者注意:30 个用户就算丰富的源了,官方客户端版本 3(v3)实际上在连接数少于 30 时会尝试增加新的连接,当连接数大于或等于 55 时会拒绝连接多余的用户。这个值对性能很重要。当完成下载一个新的片断时,“已拥有”消息(见下面)将会发送到最活动的用户。结果广播通信量与用户数目成 正比例增加。大于 25 时,新用户
28、不太可能会增加下载速度。有人强烈建议用户界面设计者使该项模糊和很难修改,因为那样做几乎没有用。3.2.3 服务器“scrape”约定根据惯例,多数服务器支持请求的另一种形式,这种方式询问给定的服务器正在处理的 torrent (或所有的 torrent)。通常叫做“刮页”(scrape page),因为它自动处理“刮屏”( screen scraping,服务器统计页)冗长的部分。刮 URL 也是一种类似于上面描述的 HTTP GET 方法。但基本 URL 不同。用以下步骤来得到刮 URL:从发布 URL 开始寻找其中最后一个“/”。如果在文本之后的“/”不是“announce”,它将被作为一
29、个符号,此符号不支持刮约定。如果是,则以“scrape” 代替“announce”来找到刮页。例:(发布 URL - scrape后的 URL) - - - - (不支持scrape) - - (不支持scrape) - (不支持scrape)此“scrape”标准是由 Bram 在 BitTorrent 开发列表文件中说明的。具体见可选参数“info_hash”可以作为scrape后的URL的一个补充,是一个 20 字节的值。为了降低服务器的负载和带宽,强烈建议软件作者尽可能使用“info_hash”参数。3.3. Peer wire protocol (用户线路协议)用户线路协议使种子文件
30、中片断(pieces)的交换变得更容易。注意原始规范在描述用户协议时也使用术语“片断”(piece),但与种子文件中的术语“片断”(piece)不同。由于该原因,在本文档中将用术语“块”(block)来描述用户之间通过线路交换的数据。客户端必须为每个远程用户的连接保持状态信息:choked(被阻塞):远程用户是否阻塞此客户端。当用户阻塞客户端时,不会响应任何请求。客户端不应尝试发送请求块,所有未响应的请求会被远程用户丢弃。interested(感兴趣): 远程用户是否对此客户端感兴趣。当客户端未阻塞时,远程用户将开始发送请求块。注意这也意味着客户端需要记住自己是否对远程用户感兴趣和阻塞它。因此
31、,真正的列表看起来像这样:am_choking:此客户端阻塞远程用户am_interseted:此客户端对远程用户感兴趣peer_chokong:远程用户阻塞此客户端peer_interested:远程用户对此客户端感兴趣客户端的连接以“被阻塞”和“不感兴趣”开始。也就是:am_choking = 1am_interested = 0peer_choking = 1peer_interested = 0当客户端对远程用户感兴趣并且远程用户未阻塞该客户端时,客户端开始下载块。当客户端没有阻塞远程用户并且远程用户对该客户端感兴趣时,客户端开始上传块。客户端保持通知远程用户自己是否对它们感兴趣,这是
32、很重要的。与每个远程用户连接的状态信息应保持最新,直到该客户端被阻塞。这允许远程用户知道当自己未阻塞时,客户端是否会开始下载;反之亦然。3.3.1 数据类型如果不特别指定,在用户线路协议中的所有整数都会编码成 4 字节 big endian(大字节序) 值,包括在握手之后所有消息中的长前缀,。3.3.2 消息流用户线路协议包括初始握手。之后,用户通过带有长度前缀消息的交换来进行通信。长度前缀是上述的一个整数。3.3.3 握手消息握手是必需的消息,它一定是由客户端发送的第一条消息,长度是(49+len(pstr) bytes。它的具体格式如下handshake::一个真实的数据包如下图所示图 3
33、 handshake消息其中,各个个字段的含义为:pstrlen:串的长度,作为单个原始字节pstr:协议的串标识符reserved:8 个保留字节。当前的执行使用全0。字节中的每位可以用来改变协议的行为。一封 Bram 的电子邮件建议首先使用末位,以使首位可用来改变末位的含义。info_hash:种子文件信息关键字的 20 字节 SHA-1 散列值。这与服务器请求中发送的 info_hash 意义相同。peer_id:每个客户端用来作为唯一标识的 20 个字节的串。这与服务器请求中发送的 peer_id 意义相同。在 BitTorrent 协议 v1.0 中:pstrlen=19,pstr=
34、BitTorrent protocol连接的发起者应该立即发送彼此的握手信息。即使接收者能同时提供多个 torrent(torrent 通过自己的 info_hash 来唯一标识),它也应等待发起者的握手信息。但是,接收者在看到握手的 info_hash 部分后必须迅速回应。服务器的 NAT 检查特性不会发送握手的 peer_id 字段。如果客户端收到一个当前不能处理的握手 info_hash,该客户端就会断开那个连接。如果连接的发起者收到一个握手信息,其中的 peer_id 与预期的不同,那么发起者就会断开该连接。注意发起者可能会收到来自服务器的远程用户信息,它包括远程用户注册的 peer_
35、id。来自服务器的 peer_id 与握手信息中的应该相同。n peer_id主要有两种将客户端及其版本信息编码到 peer_id 的方法:Azureus 型和 Shadow 型。Azureus 型使用如下编码:“-”,一个客户端标识使用两个字符,版本号用 4 个 ASCII 数字表示,“-”紧跟在随机数字之后。例如:-AZ2060-.已知采用这种方法编码的客户端是: AR - Arctic AZ - Azureus BB - BitBuddy BC - BitComet BS - BTSlave BX - Bittorrent X CD - Enhanced CTorrent CT - CT
36、orrent LP - Lphant LT - libtorrent lt - libTorrent MP - MooPolice MT - MoonlightTorrent QT - Qt 4 Torrent example RT - Retriever SB - Swiftbit SS - SwarmScope SZ - Shareaza TN - TorrentDotNET TR - Transmission TS - Torrentstorm UT - Torrent XT - XanTorrent ZT - ZipTorrentShadow 型采用如下编码:用 1 个 ASCII 字
37、母或数字标识客户端,3 个 ASCII 数字标识版本号,“-”紧跟在随机数字之后。例如:S587-.已知采用此种类型编码的客户端为: A - ABC O - Osprey Permaseed R - Tribler S - Shadows client T - BitTornado U - UPnP NAT Bit TorrentBram 的客户端现在采用的形式: M3-4-2-BitComet则不同。它的 peer_id 由四个 ASCII 字符组成“exbc”,后面是两个字节的“x”和“y”,之后才是随机字符。版本号“x”是在小数点前的十进制数值,“y”是小数点之后的两个十进制数值。Bit
38、Lord 使用相同的结构,但在版本号后添加“LORD”字符。一个 BitComet 的非官方补丁将“exbc”替换成了“FUTB”。BitComet 用户标识的编码在 0.59 及其以前的版本都采用的 Azureus 型。XBT Client也 有自己的风格。其 peer_id 由三个大写字母“XBT”紧跟三个代表版本号的 ASCII 数字。如果客户端处在调试阶段,第七字节则是小写字母“d”,其他情况下是“-”。之后是“-”和随机数字,大写和小写字母。例:XBT054d-表 示 0.5.4 版的开始调试阶段。Opera 8 previews采用以下结构:前面两个字符“OP”紧跟四个相等的构建号
39、。之后所有字符都是随机小写 16 进制的数字。Bits on Wheels采用格式“-BOWAxx-yyyyyyyyyyyy”,其中“y”是随机大写字母,x 取决于版本。版本 1.0.6 中 xx0C。许多客户端使用随机数字或 12 个0紧跟着随机数字(如以前旧版本的 Bram 客户端)。3.3.4 消息协议中所有发送的消息均采用“”的形式。长度前缀是一个占4 字节的值(big endian)。消息标识符是一个十进制字符。有效负载是与具体消息有关的。具体的消息种类如下所示keep-alive: “保持活动”消息是由0组成的字节串,将长前缀设为0可指定。没有消息标识符和有效负载。如果在一段时间内
40、,用户没有收到消息,它会断开连接,所以需要发送活动消息来维持连接。一条保持活动消息大概每两分钟发送一次。choke: 阻塞消息是定长的,无有效负载。unchoke: 未阻塞消息是定长的,无有效负载。interested: 感兴趣消息是定长的,无有效负载。not interested: 不感兴趣消息是定长的,无有效负载。have: 拥有消息是定长的。有效负载是刚成功下载和通过散列值校验的0基片段的索引。使用者注意:这是严格的定义,实际上会用到某些游戏程序。特别地,因为用户极不可能下载已经拥有的片断,用户可能不会选择向另一个用户宣布已拥有那个片断的消息。少量“拥有抑制”会导致拥有消息减少一半,在协
41、议前面将转化到 25-35%。恶意用户可能会选择宣布拥有别人永远不会下载的片断。因此,向普通用户发送此信息是坏主意。bitfield: 位字段消息可能在握手序列发送完成后,在其他任何消息发送之前立即发送。它是可选的,如果客户端没有此片断则不必发送。位字段消息是变长的,其中的“X”是位字段的长度。有效负载是代表成功下载片断的位字段。首字节的高位对应片断索引 0。已清除的位则指出缺少的片断,通过一个有效可用的片断来设置位。末位剩下的位设置为0。一个错误长度的位字段被认为是错误。客户端在收到不正确大小的位字段或已有设置为剩下位的位字段时应断开连接。request: 请求消息是定长的,用来请求块。有效
42、负载包含以下信息:索引:指定0基片断索引的整数。开始:指定片断内0基字节的偏移量整数。长度:指定被请求长度的整数。根据官方规范有关主要版本3,“所有当前执行应使用 215(32 KB),请求数量大于 217 (128 KB)时应断开连接。”在主要版本4中,此反应修改到了 214 (16 KB),超过该值的用户会强迫拒绝。注意到块请求小于片断大小(=218 字节),所以为下载一个完整片断需要多次请求。由于新版本将限制定在 16 KB,尝试使用 32 KB 的块就好比用 4 发子弹来玩俄式轮盘会遇到困难。更小的请求会导致更大的系统时间和空间开销,因为要跟踪很多请求。结果应使用所有客户端都允许的 1
43、6 KB。请求块大小的限制执行的选择没有减少一部分清楚。在主要版本 4 中,强制使用 16 KB 的请求,许多客户端会使用该值,只有一个严格客户端组不会使用。大多数旧客户端使用 32 KB 请求,不允许明显减少可能用户的批次。同时 16 KB 是现在部分官方的限制(“部分”是因为官方协议文档没有更新),所以强制使用没有错。另外,允许更大的请求增大了可能用户的批次,除在非常低的带宽连接 (小于 256 kbps)中,多个块会在一个阻塞周期内完成下载,从而强迫使用旧的限制仅会降低很少的性能。因此,推荐仅在旧的 128 KB 下才强行限制。piece: 片断消息是变长的,其中的“X”是块长度。有效负
44、载包含以下信息:索引:由0基片断索引指定的整数开始:由片断内0基字节偏移量指定的整数块:数据块,是索引指定片断的子集。cancel: 取消信息是定长的,用来取消块的请求。有效负载与“请求”消息相同。典型用在“最后阶段”中。(见下面的算法段)port: 端口消息是由运行 DHT 服务器的新版本的主要部分。监听端口是用户 DHT 节点正在监听的端口。如果 DHT 服务器支持,则应把此用户加入本地的路由表中一个真实的数据包如下图所示图 4 Piece消息其中data in a piece 就是该消息承载的真正的数据,这是整个文件中的一小片(piece)。当所有的片都被下载下来,整个下载就完成了,当然,此时上传仍然在进行。附录1 B编码B编码是一种以简洁格式指定和组织数据的方法。支持下列类型:字节串、整数、表和字典。字符串字节串按如下编码:注意没有开始和