`
shonelau
  • 浏览: 17047 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

BitTorrent 协议规范

阅读更多

翻译:小马哥
日期:2004-5-22

BitTorrent 是一种分发文件的协议。它通过URL来识别内容,并且可以无缝的和web进行交互。它基于HTTP协议,它的优势是:如果有多个下载者并发的下载同一个文件,那么,每个下载者也同时为其它下载者上传文件,这样,文件源可以支持大量的用户进行下载,而只带来适当的负载的增长。(译注:因为大量的负载被均衡到整个系统中,所以提供源文件的机器的负载只有少量增长)

一个BT文件分布系统由下列实体组成:
一个普通的web服务器
一个静态的“元信息”文件
一个跟踪(tracker)服务器
终端用户的web浏览器
终端下载者

理想的情况是多个终端用户在下载同一个文件。
要提供文件共享,那么一台主机需要执行以下步骤:
Ø运行一个 tracker服务器(或者,已经有一个tracker服务器在运行了也可以)
Ø运行一个web服务器,例如apache,或者已经有一个web服务器在运行了。
Ø在web服务器上,将文件扩展名.torrent 和MIME类型 application/x-bittorrent关联起来(或者已经关联了)
Ø根据 tracker服务器的 URL 和要共享的文件来创建一个“元信息”文件(.torrent)。
Ø将“元信息”文件发布到web服务器上
Ø在某个web页面上,添加一个到“元信息”文件的链接。
Ø运行一个已经拥有完整文件的下载者(被成为’origin’,或者’seed’,种子)

要开始下载文件,那么终端用户执行以下步骤:
Ø安装 BT(或者已经安装)
Ø访问提供 .torrent 文件的web服务器
Ø点击到 .torrent 文件的链接(译注:这时候,bt会弹出一个对话框)
Ø选择要把下载的文件保存到哪里?或者是一次断点续传
Ø等待下载的完成。
Ø结束bt程序的运行(如果不主动结束,那么bt会一直为其它人提供文件上传)

各个部分之间的连通性如下:
网站负责提供一个静态的文件,而把BT辅助程序(客户端)放在客户端机器上。
Trackers从所有下载者处接收信息,并返回给它们一个随机的peers的列表。这种交互是通过HTTP或HTTPS协议来完成的。
下载者周期性的向tracker登记,使得tracker能了解它们的进度;下载者之间通过直接连接进行数据的上传和下载。这种连接使用的是 BitTorrent 对等协议,它基于TCP。
Origin只负责上传,从不下载,因为它已经拥有了完整的文件。Origin是必须的。

元文件和tracker的响应都采用的是一种简单、有效、可扩展的格式,被称为bencoding,它可以包含字符串和整数。由于对不需要的字典关键字可以忽略,所以这种格式具有可扩展性,其它选项以后可以方便的加进来。

Bencoding格式如下:
对于字符串,首先是一个字符串的长度,然后是冒号,后面跟着实际的字符串,例如:4:spam,就是“ spam”
整数编码如下,以 ‘i’ 开始,然后10进制的整数值,最后以’e’结尾。例如,i3e表示3,I-3e表示-3。整数没有大小限制。I-0e是无效的。除了 i0e外,所以以0起始的整数都无效。I0e当然表示0。
列表编码如下,以’l’开始,接下来是列表值的编码(也采用bencoded编码),最后以’e’结束。例如:l4:spam4:eggse 表示 [‘spam’, ‘eggs’]。
字典编码如下,以’d’开始,接下来是可选的keys和它对应的值,最户以’e’结束。例如:d3:cow3:moo4:spam4:eggse,表示 {‘cow’:’moo’,’spam’:’eggs’},而d4:spaml1:al:bee 表示 {‘spam’:[‘a’,’b’]}。键值必须是字符串,而且已经排序(并非是按照字母顺序排序,而是根据原始的字符串进行排序)。

元文件是采用bencoded编码的字典,包括以下关键字:

announce tracker的服务器

info 它实际上是一个字典,包括以下关键字:

Name:
一个字符串,在保存文件的时候,作为一个建议值。仅仅是个建议而已,你可以用别的名字保存文件。
Piece length:
为了更好的传输,文件被分隔成等长的片断,除了最后一个片断以外,这个值就是片断的大小。片断大小几乎一直都是2的幂,最常用的是 256k(BT的前一个版本3.2,用的是1M作为默认大小)
Pieces:
一个长度为20的整数倍的字符串。它将再被分隔为20字节长的字符串,每个子串都是相应片断的hash值。

此外,还有一个length或files的关键字,这两个关键字只能出现一个。如果是length,那么表示要下载的仅仅是单个文件,如果是files那么要下载的是一个目录中的多个文件。
如果是单个文件,那么length是该文件的长度。

为了能支持其它关键字,对于多个文件的情况,也把它当作一个文件来看,也就是按照文件出现的顺序,把每个文件的信息连接起来,形成一个字符串。每个文件的信息实际上也是一个字典,包括以下关键字:
Length:文件长度
Path:子目录名称的列表,列表最后一项是文件的实际名称。(不允许出现列表为空的情况)。
Name:在单文件情况下,name是文件的名称,而在多文件情况下,name是目录的名称。

Tracker 查询。Trakcer通过HTTP的GET命令的参数来接收信息,而响应给对方(也就是下载者)的是经过bencoded编码的消息。注意,尽管当前的 tracker的实现需要一个web服务器,它实际上可以运行的更轻便一些,例如,作为apache的一个模块。
Tracker GET requests have the following keys:

发送给Tracker的GET请求,包含以下关键字:

Info_hash:
元文件中info部分的sha hash,20字节长。这个字符创几乎肯定需要被转义(译注:在URL中,有些字符不能出现,必须通过unicode进行编码)

Peer_id:
下载者的id,一个20字节长的字符串。每个下载者在开始一次新的下载之前,需要随机创建这个id。这个字符串通常也需要被转义。

Ip:
一个可选的参数,给出了peer的ip地址(或者dns名称?)。通常用在origin身上,如果它和tracker在同一个机器上。

Port:
peer所监听的端口。下载者通常在在 6881 端口上监听,如果该端口被占用,那么会一直尝试到 6889,如果都被占用,那么就放弃监听。

Uploaded:
已经上载的数据大小,十进制表示。

Downloaded:
已经下载的数据大小,十进制表示

Left:
该peer还有多少数据没有下载完,十进制表示。注意,这个值不能根据文件长度和已下载数据大小计算出来,因为很可能是断点续传,如果因为检查文件完整性失败而必须重新下载的时候,这也提供了一个机会。

Event:
一个可选的关键字,值是started、compted或者stopped之一(也可以为空,不做处理)。如果不出现该关键字,。在一次下载刚开始的时候,该值被设置为started,在下载完成之后,设置为completed。如果下载者停止了下载,那么该值设置为stopped。

Tracker 的响应是用bencoded编码的字典。如果tracker的响应中有一个关键字failure reason,那么它对应的是一个字符串,用来解释查询失败的原因,其它关键字都不再需要了。否则,它必须有两个关键字:Interval:下载者在两次发送请求之间的时间间隔。Peers:一个字典的列表,每个字典包括以下关键字:Peer id,Ip,Port,分别对应peer所选择的id、ip地址或者dns名称、端口号。注意,如果某些事件发生,或者需要更多的peers,那么下载者可能不定期的发送请求,

(downloader 通过 HTTP 的GET 命令来向 tracker 发送查询请求,tracker 响应一个peers 的列表)

如果你想对元信息文件或者tracker查询进行扩展,那么需要同Bram Cohen协调,以确保所有的扩展都是兼容的。

BT对等协议基于TCP,它很有效率,并不需要设置任何socket选项。(译注:BT对等协议指的是peer与peer之间交换信息的协议)
对等的两个连接是对称的,消息在两个方向上同样的传递,数据也可以在任何一个方向上流动。
一旦某个peer下载完了一个片断,并且也检查了它的完整性,那么它就向它所有的peers宣布它拥有了这个片断。
连接的任何一端都包含两比特的状态信息:是否choked,是否感兴趣。Choking是通知对方,没有数据可以发送,除非unchoking发生。Choking的原因以及技术后文解释。

一旦一端状态变为interested,而另一端变为非choking,那么数据传输就开始了。(也就是说,一个peer,如果想从它的某个peer那里得到数据,那么,它首先必须将它两之间的连接设置为 interested,其实就是发一个消息过去,而另一个peer,要检查它是否应该给这个家伙发送数据,如果它对这个家伙是 unchoke,那么就可以给它发数据,否则还是不能给它数据)Interested状态必须一直被设置――任何时候。要用点技巧才能比较好的实现这个目的,但它使得下载者能够立刻知道哪些peers将开始下载。

对等协议由一个握手开始,后面是循环的消息流,每个消息的前面,都有一个数字来表示消息的长度。握手的过程首先是先发送19,然后发送“BitTorrent protocol”。19就是“BitTorrent protocol”的长度。
后续的所有的整数,都采用big-endian 来编码为4个字节
在协议名称之后,是8个保留的字节,这些字节当前都设置为0。
接下来对元文件中的 info 信息,通过 sha1 计算后得到的 hash值,20个字节长。接收消息方,也会对 info 进行一个 hash 运算,如果这两个结果不一样,那么说明对方要的文件,并不是自己所要提供的,所以切断连接。

接下来是20个字节的 peer id。
这就是握手过程

接下来就是以消息长度开始的消息流,这是可选的。长度为0 的消息,用于保持连接的活动状态,被忽略。通常每隔2分钟发送一个这样的消息。

其它类型的消息,都有一个字节长的消息类型,可能的值如下:

‘choke’, ‘unchoe’, ‘interested’, not interested’类型的消息不再含有其它数据了。

‘bitfield’永远也仅仅是第一个被发送的消息。它的数据实际是一个位图,如果downloader已经发送了某个片断,那么对应的位置1,否则置0。Downloaders如果一个片断也没有,可以忽略这个消息。(通过这个消息,能知道什么了?)

‘have’类型的消息,后面的数据是一个简单的数字,它是下载者刚刚下载完并检查过完整性的片断的索引。(由此,可以看到,peer通过这种消息,很快就相互了解了谁都有什么片断)

‘request’类型的消息,后面包含索引、开始位置和长度)长度是2的幂。当前的实现都用的是215 ,而关闭连接的时候,请求一个超过2 17的长度。(这种类型的消息,就是当一个peer希望另一个peer给它提供片断的时候,发出的请求)

‘cancel’ 类型的消息,它的数据和’request’消息一样。它们通常只在下载趋向完成的时候发送,也就是在‘结束模式“阶段发送。在一次下载接近完成的时候,最后的几个片断需要很长时间才能下载完。为了确保最后几个片断尽快下载完,它向所有的peers发送下载请求。为了保证这不带来可怕的低效,一旦某个片断下载完成,它就其它peers发送’cancel’消息。(意思就是说,我不要这个片断了,你要是准备好了,也不用给我发了,可以想象,如果对方还是把数据发送过来了,那么这边必须忽略这些重复的数据)。

‘piece’类型的消息,后面保护索引号、开始位置和实际的数据。注意,这种类型的消息和 ‘request’消息之间有潜在的联系(译注:因为通常有了request消息之后,才会响应‘piece’消息)。如果choke和unchoke消息发送的过于迅速,或者,传输速度变的很慢,那么可能会读到一些并不是所期望的片断。( 也就是说,有时候读到了一些片断,但这些片断并不是所想要的)

分享到:
评论

相关推荐

    BitTorrent 协议规范(翻译)[PDF]

    ### BitTorrent 协议规范详解 #### 一、BitTorrent 概述 BitTorrent(简称BT)是一种分布式文件分享协议,旨在实现高效、大规模的数据分发。与传统的HTTP下载方式不同,BitTorrent允许用户在下载文件的同时也上传...

    ttorrent:带跟踪器和下载客户端的BitTorrent Java库

    Ttorrent支持以下BEP(BitTorrent增强建议): BEP#0003 :BitTorrent协议规范这是Ttorrent完全实现的基本官方协议规范。 BEP#0012 :多跟踪器元数据扩展对announce-list元信息键的完全支持,提供了分层的跟踪器...

    由Delphi实现的BT下载器示例程序

    描述中提到“包含BitTorrent协议规范资料”,这表明该压缩包可能不仅包含源代码,还可能有相关的协议文档或教程,帮助开发者理解BT协议的工作原理和如何在Delphi环境下实现它。BitTorrent协议是一种点对点(P2P)...

    bit-torrent:使用Python + asyncio构建的BitTorrent客户端

    BitTorrent协议规范( ,一些新增内容) Multitracker元数据扩展( ) (部分) UDP跟踪器协议( ) 跟踪器返回紧凑的对等列表( ) 建筑 在这个项目中,我尝试避免使用线程,而仅使用异步I / O

    bittorrent.cr:Crystal用Crystal编写的BitTorrent库和CLI

    它是用Crystal编写的一个完整的BitTorrent库,遵循BitTorrent协议规范,提供下载和上传功能。库的设计目标是简洁、高效和易于理解,使得开发者可以方便地集成到自己的项目中。它包含了对Tracker的交互,这是...

    基于BitTorrent协议的DHT网络bt种子爬虫.zip

    爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续...然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。

    BitTorrent源码+开发文档

    1. **协议规范**:详细描述BitTorrent协议的各个部分,如BEP(BitTorrent扩展协议)文档,解释了如何进行握手、交换块、交换元数据以及使用扩展协议进行更高效的数据传输。 2. **设计原理**:解释BitTorrent如何...

    DHT协议规范参考文档

    《DHT协议规范参考文档》深入解析 BitTorrent的DHT(分布式哈希表)协议是一种去中心化的网络架构,旨在解决BT客户端寻找其他下载同伴(peers)的问题,从而避免依赖中心化的Tracker服务器。DHT协议使得每个BT...

    hstorrent:Haskell 中的 BitTorrent 库

    数字描述地位3 BitTorrent 协议规范✗ 4 已知号码分配✗ 20 对等 ID 约定✗ 1000 待定标准跟踪文件✗ 9 对等点发送元数据文件的扩展✗ 23 跟踪器返回紧凑的对等列表✗ 5 DHT协议✗ 6 快速扩展✗ 7 IPv6 跟踪器扩展...

    BitTorrent:C 语言中的 BitTorrent 协议

    在 C 语言中实现 BitTorrent 协议涉及到对协议规范的理解以及对网络编程的扎实基础。下面我们将详细探讨 BitTorrent 协议的核心概念和 C 语言实现时的关键技术。 1. **BitTorrent 协议基本概念** - **Tracker**: ...

    Bittorrent Protocol Specification v1[PDF]

    - **主要目标**: 该规范的主要目的是详尽地记录BitTorrent协议的第1.0版本。这包括了所有必要的通信规则和技术细节,以便开发者能够理解和实现该协议。 #### 三、范围 - **覆盖范围**: 规范涵盖了BitTorrent协议的...

    wlan标准协议收集(包含80211和p2p协议)

    附件资源包含文件列表如下 802.11_interp.pdf 802.11-2007.pdf 802.11k-2008.pdf 802.11r-2008.pdf 802.11y-2008.pdf IEEE802.11-2012.pdf Wi-Fi_P2P_Technical_Specification_v1.7.pdf

    TorrentSniffer-开源

    TorrentSniffer是一个Java库,用于读取BitTorrent信息。 TorrentSniffer当前实现了BitTorrent协议规范1.0的以下部分:元信息文件结构,Bencoding和Tracker'scrape'约定。

    BitTorrentSpecification v1.0.pdf

    本规范的主要目的是详尽地记录BitTorrent协议版本1.0的各项特性和技术细节。相较于Bram Cohen最初发布的较为通用的协议描述,本规范在某些方面提供了更深入的行为细节描述,力求成为一份正式的技术规范文档。 #### ...

    点对点网络:协议,合作,与竞争

    - **Kademlia**:一种分布式哈希表(DHT),用于查找和存储数据,常用于BitTorrent协议中。 #### 四、P2P网络中的合作与竞争 ##### 4.1 合作机制 在P2P网络中,合作对于网络的有效运作至关重要。合作可以通过以下...

    Node.js-FederatedActivityPub视频流媒体平台直接在Web浏览器中使用P2P(BitTorrent)与WebTorrent

    这个协议基于Activity Streams规范,使得用户可以在一个平台上发布内容,而其他平台上的用户也能看到和互动。Federated ActivityPub在视频流媒体平台的应用意味着用户可以跨多个独立的服务器分享和观看视频,实现去...

    cratetorrent:一个用于Rust(目前为Linux)的BitTorrent V1引擎库

    2. **BitTorrent协议V1**:理解BitTorrent协议的工作原理,包括信息交换、碎片下载、文件校验、Tracker服务器和DHT(分布式哈希表)等。 3. **P2P网络**:掌握P2P网络的架构,包括节点发现、数据传输、带宽管理等,...

Global site tag (gtag.js) - Google Analytics