Peer wire protocol (TCP)

概述

peer(端)协议使片(piece)的交换变得容易,片的描述请参考元信息文件。

注意:原来的规范在描述peer协议时,也使用术语piece“(片)”,但是这不同于元信息文件里面的术语“piece(片)”,由于这个原因,在本规范中,将使用术语“块(block)”来描述peers(端)之间交换的数据。

一个客户端(client)必须维持其与每一个远程peer(端)连接的状态信息:

choked: 远程peer(端)是否已经choke本客户端。当一个peer(端) choke本客户端后,它是在通知本客户端,除非它unchoke本客户端,否则它不会应答该客户端所发出的任何请求。本客户端也不应该试图向远程peer发送数据请求,并且应该认为所有没有应答的请求已经被远程peer丢弃。

interested: 远程peer(端)是否对本客户端提供的数据感兴趣。这是远程peer在通知本客户端,当本客户端unchoke他们时,远程客户端将开始请求块(block)。

注意这也意味着本客户端需要记录它是否对远程peer(端)感兴趣,以及它是否choke/unchoke远程peer。因此真正的列表看起来像这样:

am_choking: 本客户端正在choke远程peer。

am_interested: 本客户端对远程peer感兴趣。

peer_choking: 远程peer正choke本客户端。

peer_interested: 远程peer对本客户端感兴趣。

客户端连接开始时状态是choke和not interested(不感兴趣)。换句话就是:

am_choking = 1

am_interested = 0

peer_choking = 1

peer_interested = 0

当一个客户端对一个远程peer感兴趣并且那个远程peer没有choke这个客户端,那么这个客户端就可以从远程peer下载块(block)。当一个客户端没有choke一个peer,并且那个peer对这个客户端这个感兴趣时,这个客户端就会上传块(block)。

客户端必须不断通知它的peers,它是否对它们感兴趣,这一点是很重要的。客户端和每个端的状态信息必须保持最新,即使本客户端被choke。这允许所有的peer知道,当它们unchoke该客户端后,该客户端是否开始下载(反之亦然)。

数据类型

如果没有用其他的方法指定,在peer wire协议中的所有整数都会编码为4个字节的大端(big-endian)值。这也包括在握手之后,所有报文(Message)的长度前缀。

报文流(Message flow)

(译者注:因为ICMP-Internet控制报文协议中的Message翻译成报文,同时IP/TCP层中传输的数据都翻译为数据报,应用层传输的数据都翻译成报文,因此在这里Message翻译成报文)

peer wire协议由一个初始的握手组成。握手之后,peers通过以长度为前缀消息的交换进行通信。长度前缀就是上面描述的整数。

握手(HandShake)

握手是一个必需的报文,并且必须是客户端发送的第一个报文。该握手报文的长度是(49+len(pstr))字节。

握手:handshake: <pstrlen><pstr><reserved><info_hash><peer_id>

pstrlen: <pstr>的字符串长度,单个字节。

pstr: 协议的标识符,字符串类型。

reserved: 8个保留字节。当前的所有实现都使用全0.这些字节里面的每一个字节都可以用来改变协议的行为。来自Bram的邮件建议应该首先使用后面的位,以便可以使用前面的位来改变后面位的意义。

info_hash: 元信息文件中info键(key)对应值的20字节SHA1哈希。这个info_hash和在tracker请求中info_hash是同一个。

peer_id: 用于唯一标识客户端的20字节字符串。这个peer_id通常跟在tracker请求中传送的peer_id相同(但也不尽然,例如在Azureus,就有一个匿名选项)。

在BitTorrent协议1.0版本,pstrlen = 19, pstr = “BitTorrent protocol”。

连接的发起者应该立即发送握手报文。如果接收方能够同时地服务多个torrent,它会等待发起者的握手报文(torrent由infohash唯一标识)。尽管如此,一旦接收方看到握手报文中的info_hash部分,接收方必须尽快响应。tracker的NAT-checking特性不会发送握手报文的peer_id字段。

如果一个客户端接收到一个握手报文,并且该客户端没有服务这个报文的info_hash,那么该客户端必须丢弃该连接。

如果一个连接发起者接收到一个握手报文,并且该报文中peer_id与期望的peer_id不匹配,那么连接发起者应该丢弃该连接。注意发起者可能接收来自tracker的peer信息,该信息包含peer注册的peer_id。来自于tracker的peer_id需要匹配握手报文中的peer_id。

peer_id

peer_id长20个字节。至于怎么将客户端和客户端版本信息编码成peer_id,现在主要有两种惯例:Azureus风格和Shadow风格。

Azureus风格使用如下编码方式:’-’, 紧接着是2个字符的client id,再接着是4个数字的版本号,’-’,后面跟着随机数。

例如:'-AZ2060-'...

使用这种编码风格的知名客户端是:

l  'AG' - Ares

l  'A~' - Ares

l  'AR' - Arctic

l  'AT' - Artemis

l  'AX' - BitPump

l  'AZ' - Azureus

l  'BB' - BitBuddy

l  'BC' - BitComet

l  'BF' - Bitflu

l  'BG' - BTG (uses Rasterbar libtorrent)

l  'BP' - BitTorrent Pro (Azureus + spyware)

l  'BR' - BitRocket

l  'BS' - BTSlave

l  'BW' - BitWombat

l  'BX' - ~Bittorrent X

l  'CD' - Enhanced CTorrent

l  'CT' - CTorrent

l  'DE' - DelugeTorrent

l  'DP' - Propagate Data Client

l  'EB' - EBit

l  'ES' - electric sheep

l  'FC' - FileCroc

l  'FT' - FoxTorrent

l  'GS' - GSTorrent

l  'HL' - Halite

l  'HN' - Hydranode

l  'KG' - KGet

l  'KT' - KTorrent

l  'LC' - LeechCraft

l  'LH' - LH-ABC

l  'LP' - Lphant

l  'LT' - libtorrent

l  'lt' - libTorrent

l  'LW' - LimeWire

l  'MO' - MonoTorrent

l  'MP' - MooPolice

l  'MR' - Miro

l  'MT' - MoonlightTorrent

l  'NX' - Net Transport

l  'OT' - OmegaTorrent

l  'PD' - Pando

l  'qB' - qBittorrent

l  'QD' - QQDownload

l  'QT' - Qt 4 Torrent example

l  'RT' - Retriever

l  'RZ' - RezTorrent

l  'S~' - Shareaza alpha/beta

l  'SB' - ~Swiftbit

l  'SS' - SwarmScope

l  'ST' - SymTorrent

l  'st' - sharktorrent

l  'SZ' - Shareaza

l  'TN' - TorrentDotNET

l  'TR' - Transmission

l  'TS' - Torrentstorm

l  'TT' - TuoTu

l  'UL' - uLeecher!

l  'UM' - µTorrent for Mac

l  'UT' - µTorrent

l  'VG' - Vagaa

l  'WT' - BitLet

l  'WY' - FireTorrent

l  'XL' - Xunlei

l  'XT' - XanTorrent

l  'XX' - Xtorrent

l  'ZT' - ZipTorrent

另外还需要识别的客户端有:

l  'BD' (例如: -BD0300-)

l  'NP' (例如: -NP0201-)

l  'SD' (例如: -SD0100-)

l  'wF' (例如: -wF2200-)

l  'hk' (例如: -hk0010-) 中国IP地址,IP address, unrequestedly sends info dict in message 0xA, reconnects immediately after being disconnected, reserved bytes = 01,01,01,01,00,00,02,01

Shadow风格使用如下编码方式:一个用于客户端标识的ASCII字母数字,多达五个字符的版本号(如果少于5个,则以’-’填充),紧接着是3个字符(通常是’---’,但也不总是这样),最后跟着随机数。版本字符串中的每一个字符表示一个0到63的数字。'0'=0, ..., '9'=9, 'A'=10, ..., 'Z'=35, 'a'=36, ..., 'z'=61, '.'=62, '-'=63。

你可以在这找到关于shadow编码风格(包含关于版本字符串后的三个字符用法的习惯)的详细说明。

例如:用于Shadow 5.8.11的’S58B-----‘...

使用这种编码风格的知名客户端是:

l  'A' - ABC

l  'O' - Osprey Permaseed

l  'Q' - BTQueue

l  'R' - Tribler

l  'S' - Shadow's client

l  'T' - BitTornado

l  'U' - UPnP NAT Bit Torrent

Bram的客户端现在使用这种风格:'M3-4-2--' or 'M4-20-8-'。

BitComet使用不同的编码风格。它的peer_id由4个ASCII字符’exbc’组成,接着是2个字节的x和y,最后是随机字符。版本号中的x在小数点前面,y是版本号后的两个数字。BitLord使用相同的方案,但是在版本号后面添加’LORD’。BitComet的一个非正式补丁曾经使用’FUTB’代替’exbc’。自版本0.59开始,BitComet peer id的编码使用Azureus风格。

XBT客户端也使用其特有的风格。它的peer_id由三个大写字母’XBT’以及紧随其后的代表版本号的三个ASCII数字组成。如果客户端是debug版本,第七个字节是小写字符’d’,否则就是’-‘。接着就是’-‘,然后是随机数,大写和小写字母。例如:peer_id的开始部分为'XBT054d-'表明该客户端是版本号为0.5.4的debug版本。

Opera 8预览版和Opera 9.x发行版使用以下的peer_id方案:开始的两个字符是’OP’,后面的四个数字是开发代号。接着的字符是随机的小写十六进制数字。

MLdonkey使用如下的peer_id方案:开始的字符是’-ML’,后面跟着点式版本,然后就是一个’-’,最后跟着随机字符串。例如:'-ML2.7.2-kgjjfkd'。

Bit on Wheels使用模式'-BOWxxx-yyyyyyyyyyyy',其中y是随机的(大写字母),x依赖于版本。如果版本为1.0.6,那么xxx = AOC。

Queen Bee使用Bram的新风格:'Q1-0-0--' or 'Q1-10-0-'之后紧随着随机字节。

BitTyrant是Azureus的一个分支,在它的1.1版本,其peer id使用'AZ2500BT' + 随机字节的方式。

TorrenTopia版本1.90自称是或源自于Mainline 3.4.6。它的peer ID以'346------'开始。

BitSpirit有几种编码peer ID的方式。一种模式是读取它的peer ID然后使用开始的八个字节作为它peer ID的基础来重新连接。它的实际ID使用'/0/3BS'(c 标记法)作为版本3.x的前四个字节,使用'/0/2BS'作为版本2.x的前四个字节。所有方式都使用'UDP0'作为结尾。

Rufus使用它的十进制ASCII版本值作为开始的两个字节。第三个和第四个字节是'RS'。紧随其后的是用户的昵称和一些随机字节。

C3 Torrent的peer ID以’-G3’开始,然后追加多达9个表示用户昵称的字符。

FlashGet使用Azureus风格,但是前面字符是’FG’,没有’-’。版本 1.82.1002 仍然使用版本数字 '0180'。

BT Next Evolution源自于BitTornado,但是试着模仿Azureus风格。结果是它的peer ID以’-NE’开始,接着是四个数字的版本号,最后就是以shadow peer id风格描述客户端类型的三个字符。

所有Peers使用一个特定于用户的字符串的Sha1哈希值,使用"AP" + version string + "-"代替开始的一些字符。

Qvod的id以四个字母"QVOD"开始,接着是4个十进制数字的开发代号(目前是” 0054”)。最后的12个字符是随机的大写十六进制数字。中国有一个修改版,该版本以随机字节代替前四个字符。

许多客户端全部使用随机数或者随机数后面跟12个全0(像Bram客户端的老版本)。

报文(Messages)

接下来协议的所有报文采用如下的结构:<length prefix><message ID><payload>。length prefix(长度前缀)是一个4字节的大端(big-endian)值。message ID是单个十进制值。playload与消息相关。

keep-alive: <len=0000>

keep-alive消息是一个0字节的消息,将length prefix设置成0。没有message ID和payload。如果peers在一个固定时间段内没有收到任何报文(keep-alive或其他任何报文),那么peers应该关掉这个连接,因此如果在一个给定的时间内没有发出任何命令的话,peers必须发送一个keep-alive报文保持这个连接激活。通常情况下,这个时间是2分钟。

choke: <len=0001><id=0>

choke报文长度固定,并且没有payload。

unchoke: <len=0001><id=1>

unchoke报文长度固定,并且没有payload。

interested: <len=0001><id=2>

interested报文长度固定,并且没有payload。

not interested: <len=0001><id=3>

not interested报文长度固定,并且没有payload。

have: <len=0005><id=4><piece index>

have报文长度固定。payload是piece(片)的从零开始的索引,该片已经成功下载并且通过hash校验。

实现者注意:实际上,一些客户端必须严格实现该定义。因为peers不太可能下载他们已经拥有的piece(片),一个peer不应该通知另一个peer它拥有一个piece(片),如果另一个peer拥有这个piece(片)。最低限度”HAVE suppresion”会使用have报文数量减半,总的来说,大致减少25-35%的HAVE报文。同时,给一个拥有piece(片)的peer发送HAVE报文是值得的,因为这有助于决定哪个piece是稀缺的。

一个恶意的peer可能向其他的peer广播它们不可能下载的piece(片)。Due to this attempting to model peers using this information is a bad idea.

bitfield: <len=0001+X><id=5><bitfield>

bitfield报文可能仅在握手序列发送之后,其他消息发送之前立即发送。它是可选的,如果一个客户端没有piece(片),就不需要发送该报文。

bitfield报文长度可变,其中x是bitfield的长度。payload是一个bitfield,该bitfield表示已经成功下载的piece(片)。第一个字节的高位相当于piece索引0。设置为0的位表示一个没有的piece,设置为1的位表示有效的和可用的piece。末尾的冗余位设置为0。

长度不对的bitfield将被认为是一个错误。如果客户端接收到长度不对的bitfield或者bitfield有任一冗余位集,它应该丢弃这个连接。

request: <len=0013><id=6><index><begin><length>

request报文长度固定,用于请求一个块(block)。payload包含如下信息:

index: 整数,指定从零开始的piece索引。

begin: 整数,指定piece中从零开始的字节偏移。

length: 整数,指定请求的长度。

piece: <len=0009+X><id=7><index><begin><block>

piece报文长度可变,其中x是块的长度。payload包含如下信息:

index: 整数,指定从零开始的piece索引。

begin: 整数,指定piece中从零开始的字节偏移。

block: 数据块,它是由索引指定的piece的子集。

cancel: <len=0013><id<=8><index><begin><length>

cancel报文长度固定,用于取消块请求。playload与request报文的playload相同。一般情况下用于结束下载。

port: <len=0003><id=9><listen-port>

port报文由新版本的Mainline发送,新版本Mainline实现了一个DHT tracker。该监听端口是peer的DHT节点正在监听的端口。这个peer应该插入本地路由表(如果支持DHT tracker的话)。

BitTorrent协议规范(BitTorrent Protocol Specification)之Peer Wire协议(Peer Wire Protocol)-第四部分相关推荐

  1. BitTorrent协议规范(BitTorrent Protocol Specification)系列之元信息文件结构(Metainfo File Structure)-第二部分...

    元信息文件结构(Metainfo File Structure) 元信息文件里面的所有数据都以B编码方式编码,B编码规范请参考本系列文档之B编码. 元信息文件(就是平常咱们经常接触到的以.torren ...

  2. [转载] BitTorrent协议规范

    BitTorrent 协议规范(BT协议集合)一 BitTorrent 是一种分发文件的协议.它通过URL来识别内容,并且可以无缝的和web进行交互.它基于HTTP协议,它的优势是:如果有多个下载者并 ...

  3. BitTorrent协议规范(二)

    Peer wire protocol (TCP) 概述 peer(端)协议使片(piece)的交换变得容易,片的描述请参考元信息文件. 注意:原来的规范在描述peer协议时,也使用术语piece&qu ...

  4. [译]BitTorrent协议规范

    BitTorrent 是一个用于文件分发的协议.它通过 URL 来标识内容,其设计使其可以与 Web 无缝集成.BitTorrent 相对于一般 HTTP 的优势在于,当相同文件的多个下载并行进行时, ...

  5. 一个简单的BitTorrent客户端实现(六):peer manager和peer实现

    peer manager和peer peer是整个BT通信中最复杂的部分,主要是里面各种消息的发送和一些choke和unchoke策略,piece选择策略等等.peer manager用于管理peer ...

  6. BitTorrent协议规范之torrent文件

    BitTorrent下载每个资源需要一个元数据信息(meta info)文件,该文件描述资源的相关信息,其后缀名通常为.torrent,所以也叫torrent文件.   torrent文件中内容采用B ...

  7. 用eclips连hadoop报Unknown protocol to job tracker: org.apache.hadoop.hdfs.protocol.ClientProtoco

    win7上开发hadoop 在eclips连接hadoop时,报Unknown protocol to job tracker: org.apache.hadoop.hdfs.protocol.Cli ...

  8. ICMP(Internet Control Message Protocol)网际控制报文协议初识

    ICMP是(Internet Control Message Protocol)Internet控制报文协议.它是TCP/IP协议族的一个子协议,用于在IP主机.路由器之间传递控制消息.控制消息是指网 ...

  9. MTK 驱动(65)---Android 多点触摸协议(Multi-touch Protocol)

    Android 多点触摸协议(Multi-touch Protocol) Android 多点触摸协议Multi-touch Protocol A协议 B协议 代码编写 Protocol A Prot ...

  10. ADAS自动驾驶辅助系统通讯协议「ADASIS Protocol」接口定义解析(二)详细

    「ADASIS Protocol Introduction」 --信号接口解析 本文来自微信公众号:[阿波兹得][续]ADASIS Protocol介绍 (2) 信号解析https://mp.weix ...

最新文章

  1. 应用YOLOV4 - DeepSort 实现目标跟踪
  2. centos7 apache2.4 多站点配置
  3. socket通信入门
  4. java map equals_Java中EnumMap的equals()方法: Java.util.EnumMap.equals() - Break易站
  5. 论ORM框架—EntityFrameworkCore
  6. 【BZOJ28431180】极地旅行社,LCT练习
  7. ifconfig源代码-NetBSD
  8. IBM 推出世界最小电脑,应用区块链技术防偷骗!
  9. 打印时候复选框勾选不见了_请取消勾选逐份打印复选框
  10. 2022年6月青少年软件编程(图形化) 等级考试试卷(一级)
  11. 小功能⭐️Unity动态更改 Scripting Define Symbols (宏定义)
  12. 看图说话!这个 AI 商品识别系统开源了!
  13. android 瘦脸模式 sdk,大眼瘦脸加磨皮通通不能少,论美颜SDK是如何实现的
  14. java秒转换为年月日_SimpleDateFormat将月/日/年 时分秒转换为年-月-日 时:分:秒
  15. SQL Server 2012笔记分享-35:配置客户端网络协议
  16. 如何在NLP领域做成一件事by周明ACL计算语言学会候任主席(附PDF公号发“NLP做事”下载rar讲座PPT等10文件)...
  17. mybatis中resultMap和resultType的详细用法
  18. Office - PPT 02
  19. 第八周---FPGA流水灯显示和串口循环输出实验
  20. 安全多方计算-入门学习笔记(二)

热门文章

  1. php laravel 下载远程图片
  2. 【数字图像处理】实验三 图像分割(MATLAB实现)
  3. Proteus8.9 仿真数码管 闪退问题及其解决方法
  4. BC26:使用MQTT对接阿里云平台
  5. oracle存储过程导出scv文件
  6. 地图制图基础(二):地图内容
  7. Matlab计算标准时间格式下时间差
  8. 本特利探头330104-00-02-10-02-00
  9. 智能工厂信息化系统建设规划
  10. 医疗行业的信息化建设