IMFile

IMFile

A Free And Unlimited BT / HTTP / HTTPS / eD2k Download Software From Singapore

WebSeed – 基于 HTTP/FTP 做种的 BitTorrent 技术

摘要#

通过在下载过程中使用 HTTP 或 FTP 服务器向节点发送额外的数据来增加下载速度,从而减少 BitTorrent 下载中可能出现的下载停滞情况。

原理#

很多提供 BitTorrent 下载链接的网站也会同时提供相同文件的 HTTP 或 FTP URL 。这些 URL 所指向的文件是完全相同的。利用 WebSeeding 技术的 BitTorrent 客户端可以从任意一种来源(即 BitTorrent 和 HTTP 或 FTP)下载文件,将下载到的数据块组装成为一个完整的文件。 HTTP 或 FTP 服务器充当着一个始终处于未限速状态的 "种子",即它可以不间断地提供文件的数据块,以加速文件的下载。

优势#

每个 BitTorrent 下载都有一些开放下载端口的源,也就是种子,任何人都可以从这些源开始下载。

对于不能识别元数据添加的客户端,这种新方法不会破坏或更改任何内容。

不支持 HTTP/FTP 种子的 BitTorrent 客户端仍然可以通过其他支持 HTTP/FTP 的同伴来共享数据块。

无需更改元数据。下载管理工具通常可以为一个文件添加多个 HTTP/FTP 镜像网址,用户只需单击网页上多个链接并识别相同的文件名即可。

大家对 HTTP/FTP 服务器及其协议非常熟悉。

这种新方法已经在多个 BitTorrent 客户端中实现,如 IMFile 、 GetRight 、 Mainline 、 uTorrent 、 Azureus 和 libTorrent 。

只需要在 BitTorrent 客户端中进行少量更改,并且不需要更改 Tracker 、 HTTP 或 FTP 服务器。在 HTTP 或 FTP 服务器上也不需要使用脚本。

由于许多常见的客户端已经支持此功能(特别是 IMFile 客户端),因此使用公司或个人现有的 HTTP/FTP 服务器完全可以进行 BitTorrent 下载的种子发布。

元数据扩展#

在 BitTorrent 元数据文件的主要区域中,而不是 "info" 部分的一部分,将会有一个新键 "url-list" 。该键将引用一个或多个 URL 地址列表,并包含可以检索种子数据的网址列表。如果客户端无法使用此键,则可以安全地忽略它。
例:

d 8:announce27:http:tracker.com/announce
      8:url-list26:http:mirror.com/file.exe
      4:info…

如果 "url-list" URL 以斜杠 "/" 结尾,则客户端必须添加种子文件名来生成完整的 URL 。这样可以让 .torrent 生成器将此字段同等对待单文件和多文件种子。

多文件种子#

在下载多文件种子时,BitTorrent 客户端通常会使用种子文件中 "info" 部分中的 "name" 字段作为根目录,并使用 "path/file" 字段来指定在该根目录下的文件路径和名称。但是,在这个例子中,种子文件的 "url-list" 字段被用作根目录,因此客户端需要将 "name" 和 "path/file" 添加到该根目录中,以创建请求的 URL 。
例如,

... 8:url-list22:http://mirror.com/pub/ 4:infod5:filesld6:lengthi949e4:pathl10:Readme.txte e4:name7:michael

在这个例子中,客户端需要将 "name" 设置为 "michael",并将 "path/file" 中的 "Readme.txt" 文件添加到 http://mirror.com/pub/ 根目录中,以生成下载请求的 URL 。客户端将使用上述步骤生成的根目录、文件路径和文件名称,将它们拼接起来,生成一个完整的下载请求 URL:http://mirror.com/pub/michael/Readme.txt

客户端实现概述#

首先,客户端应该忽略它不认识的协议,因为如果尝试连接这样的协议可能会导致错误。例如,一个客户端可能只支持 HTTP 而不支持 FTP,或者反过来。

其次,HTTP 和 FTP 协议都是流式传输的协议,而没有 BitTorrent 中所谓的数据块的概念。这意味着当使用 HTTP 或 FTP 下载时,会出现很多数据空隙,因为无法像 BitTorrent 那样对文件进行分块下载。

为了解决这个问题,对实现中的 "最稀缺优先" 块选择方法进行了修改,使得下载的文件中存在更多的数据空隙,这样 HTTP 和 FTP 线程就可以从这些空隙开始下载,直到填满整个空隙。可以使用 HTTP 的字节范围请求功能来请求单个块,但这可能会被服务器记录下来,并被误认为是针对该服务器的 DoS 攻击。

客户端实现注意事项#

为了让 HTTP 和 FTP 连接更好地填充文件中的很多连续块,BitTorrent 的标准算法进行了一些更改。

空隙的定义#

空隙指的是客户端没有的多个相邻块所组成的空间。在这个例子中,假设有一个位域 "YYnnnnYnnY",其中 Y 表示客户端拥有的块,n 表示客户端没有的块。那么,在该位域中就存在两个空隙,分别是长度为 4 和长度为 2 的相邻未下载的块组成的空间。

下载块的选择#

最主要的变化是下载块的选择,如果所有缺失块的稀有度相似,那么在请求一个块时,最好从长度为 2 的间隙中选择一个块开始下载。而在任何间隙中,最好从结尾开始填充 (即优先选择最高编号的块) 。因此,在给定的位域 "YYnnnnYnnY" 中,如果缺失块的稀有度相似,则最好选择 "# pieces YYnnnnY##Y" 中的一个块进行下载,其中最佳的选择是选择块 "$ YYnnnnYn$Y" 。

这些块选择策略可以最大程度地利用 HTTP/FTP 连接的连续数据下载。这样,HTTP/FTP 连接可以从间隔的开头开始下载,并在连接到客户端已有的块之前尽可能多地下载数据。

更改块选取策略#

将下载块选取策略从原来的 "先选最稀有的" 修改为 "优先选取与已完成块距离最远且相对稀有的" 。

最罕见且最大间隔的块#

首先找到当前所有未下载块中出现频率最少的块,即 PRWBG(Pretty Rare With Biggest Gap - 最罕见且最大间隔的块),假设它距离已经下载完成的另一块的距离为 D 。

对于其他未下载块,如果它们与已下载块的距离小于 D,则认为它们比 PRWBG 更罕见,因此被标记为 "罕见 - X"(其中 X 是一个常数,等于 "对等方数量减 1 的平方根")。

相反地,如果某个未下载块与已下载块之间的距离大于 D,则认为它可能比 PRWBG 更容易获得,并被标记为 "罕见 + X",以备可能选择作为下一个下载块。

如果当前最稀有的一块只有 3 个节点拥有,那么通常的算法会选择另外两个节点也有的拼。但是,如果使用修改后的算法,当一块距离完整文件的距离小于当前最稀有块的间隔时,只需要有 1 个节点拥有这一块即可选择它。

如果间隔更大且该块的 "稀有程度" 与通常的 "稀有 - 1" 相同,那么将选择这一块(因此,如果间隔更大,则会选择具有 2 或 3 个节点拥有的块)。

因此,在给定的 "YYnnn1Yn2Y" 情况下,除非 1 比 2 更稀有,否则最好选择 2 。
伪代码逻辑:

X = sqrt(Peers) - 1;
      Gap = 0;
      CurGap = 0;
      CurRarest = MaxPieces+1;
      for (i=0; i<MaxPieces; i++) {
          if (IDoNotHavePiece(i)) {
              Gap++;
              if (PeerHasPiece(i)) {
                  PieceRareness = NumberOfPeersWithThePiece();
                  if (PieceRareness<(CurRarest-X) ||
                      (PieceRareness<=(CurRarest+X) && Gap>CurGap)) {
                      CurRarest = PieceRareness;
                      CurGap = Gap;
                      NextPiece = i;
                  }
              }
          } else {
              Gap = 0;
          }
      }

填补空隙#

当一个文件已经完成了 50% 以上时,使用不同的方法随机选择下载块。(在 50% 以上,你应该有大量其他节点想要下载的块。)

每隔几个块,它会选择距离完整文件最近的块,忽略所有的稀有度。例如,在位域 "YYnnnnYnnY" 中,它将选择块 #"YYnnnnYn#Y" 。这有助于填补小缺口。

客户端可以选择是否执行此步骤,如果实现此功能,还可以使用另一个文件完成百分比。

伪代码逻辑:

Gap = 0;
      Piece = -1;
      CurGap = MaxPieces+1;
      for (i=0; i<MaxPieces; i++) {
          if (IDoNotHavePiece(i)) {
              Gap++;
              if (PeerHasPiece(i)) {
                  Piece = i;
              }
          } else {----
              if (Gap<CurGap && Gap>0 && Piece!=-1) {
                  CurGap = Gap;
                  NextPiece = Piece;
              }
              Gap = 0;
              Piece = -1;
          }
      }

HTTP 和 FTP 优化#

对于 HTTP/FTP 协议或服务器本身无需进行修改。

如果客户端知道 HTTP/FTP 下载是 BitTorrent 下载的一部分,则最好在第一次连接时随机选择文件中的某个位置开始下载。这样,它获得的第一批 HTTP 数据块更有可能对 BitTorrent 节点进行共享。

如果在启动 HTTP/FTP 连接时已经存在一个正在进行的 BitTorrent 下载,则 HTTP/FTP 应从最大空隙的开头开始。对于位域 "YYnnnnYnnY",它应该从#号开始:"YY#nnnYnnY" 。

如果成功从 HTTP/FTP 服务器下载了一块数据块,但 SHA 校验和不匹配,则必须关闭连接并丢弃该 URL 。

如果客户端收到 "忙" 回复,则无需放弃 HTTP 或 FTP 服务器的 URL 。

多文件种子#

当使用 HTTP/FTP 服务器进行多文件种子下载时,需要额外的选择算法来优化下载效率。

对于大型文件,客户端可以选择 BitTorrent 块以优化下载速度,从而能够从 HTTP/FTP 服务器完整地下载整个文件。

对于包含小文件的种子,可能需要进行多个 HTTP/FTP 传输才能完成一个块的下载。在这种情况下,使用 BitTorrent 进行传输可能更为合适。例如,如果有 100 个 1KB 的文件,假设块大小为 32KB,则需要进行 100 个 HTTP/FTP 传输才能完成文件的下载,但只需要 4 个 BitTorrent 块请求。

因此,将小文件给予 BitTorrent 块选择更高的优先级,将大文件给予 HTTP/FTP 更高的优先级,可以有效提高下载效率。

另一种可能的客户端实现#

如果客户端只支持 HTTP 而不支持 FTP,则可以利用 HTTP 的字节范围请求功能,但每次请求多个块。

将多个块视为单个集合,并向 HTTP 服务器发送单个字节范围请求。这将减少 HTTP 连接的数量,并且对于客户端可能会有很好的效果。

可以将块视为 10 、 50 或 100 个块。如果按照这种方式进行处理,"Pieces Per Block" 可以选择为 MaxPieces/20,因此每次请求约为文件的 5% 。

不建议的客户端实现#

客户端可以简单地使用 HTTP 字节范围请求来请求单个片段。但是,一些服务器管理员可能不会喜欢这种实现方式,因为针对单个文件将会在他们的日志中产生数百或数千个请求。有些人甚至可能认为这是对他们的拒绝服务攻击。

其他协议内容#

可能用于下载数据的协议。尽管在上文中列出了 HTTP/FTP 作为用于种子分享的协议,但是客户端可以使用任何允许下载数据的协议。例如 HTTPS 、 FTPS 或 SFTP 等协议也可以被使用,但可能不是所有客户端都支持。

RTSP 和 MMS 等协议也有可能被使用。甚至还可以使用 Usenet 的 NNTP 协议进行下载。

其他协议可能存在其他问题,例如不允许从文件的任意位置开始下载。

客户端可以选择仅实现 HTTP 或 FTP 协议中的一个而不是两者同时实现。

参考链接#

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。