http://www.bittorrent.org/beps/bep_0015.html
为了发现一群同伴,客户端向跟踪器宣布它的存在。使用HTTP协议,典型的请求包含以下参数:info_hash,key,peer_id,端口,下载,左,上载和压缩。响应包含对等方(主机和端口)列表以及一些其他信息。请求和响应都非常短。由于使用了TCP,因此必须打开和关闭连接,从而增加了额外的开销。
使用HTTP会带来大量开销。以太网层(每个数据包14个字节),IP层(每个数据包20个字节),TCP层(每个数据包20个字节)和HTTP层都有开销。大约有10个数据包用于包含50个对等方的请求和响应,并且使用的字节总数约为1206 [1]。通过使用基于UDP的协议,可以显着减少此开销。此处提出的协议使用4个数据包和大约618个字节,将流量减少了50%。对于客户而言,每小时节省1 KB并不重要,但是对于为100万对等端服务的跟踪器而言,将流量减少50%至关重要。另一个优点是,基于UDP的二进制协议不需要复杂的解析器,也不需要连接处理,从而降低了跟踪器代码的复杂性并提高了其性能。
在理想情况下,仅需要2个数据包。但是,可以欺骗UDP数据包的源地址。跟踪器必须确保不会发生这种情况,因此它会计算一个值(connection_id)并将其发送给客户端。如果客户端欺骗了它的源地址,它将不会收到该值(除非它正在嗅探网络)。然后,connection_id将再次在数据包3中发送给跟踪器。跟踪器将验证connection_id,如果请求不匹配,则忽略该请求。客户端不应猜测连接ID。这相当于TCP握手,并且可以使用类似syn cookie的方法在跟踪器端存储连接ID。连接ID可以用于多个请求。客户端可以使用连接ID,直到收到连接ID一分钟。
UDP是一种“不可靠”的协议。这意味着它本身不会重新传输丢失的数据包。应用程序对此负责。如果在15 * 2 ^ n秒后仍未收到响应,则客户端应重新传输请求,其中n从0开始并在每次重新传输后增加到8(3840秒)。请注意,有必要在连接ID过期时重新请求它。
正常宣布:
t = 0:连接请求 t = 1:连接响应 t = 2:宣布请求 t = 3:宣布响应
连接超时:
t = 0:连接请求 t = 15:连接请求 t = 45:连接请求 t = 105:连接请求 等
宣布超时:
t = 0: t = 0:连接请求 t = 1:连接响应 t = 2:宣布请求 t = 17:宣布请求 t = 47:宣布请求 t = 107:连接请求(因为连接ID过期) t = 227:连接请求 等
多个请求:
t = 0:连接请求 t = 1:连接响应 t = 2:宣告请求 t = 3:宣告响应 t = 4:宣告请求 t = 5:宣告响应 t = 60:宣告请求 t = 61:宣告响应 t = 62:连接请求 t = 63:连接响应 t = 64:宣布请求 t = 64:抓取请求 t = 64:抓取请求 t = 64:宣布请求 t = 65:宣布响应 t = 66:宣布响应 t = 67:刮擦响应 t = 68:刮擦响应
所有值均以网络字节顺序(大字节序)发送。不要期望数据包恰好具有一定的大小。将来的扩展可能会增加数据包的大小。
宣布或抓取之前,您必须获取连接ID。
- 选择一个随机的交易ID。
- 填写连接请求结构。
- 发送数据包。
连接请求:
偏移量大小名称值 0 64位整数protocol_id 0x41727101980 //魔术常数 8 32位整数操作0 //连接 12 32位整数transaction_id 16
- 接收数据包。
- 检查数据包是否至少为16个字节。
- 检查交易ID是否等于您选择的ID。
- 检查操作是否已连接。
- 存储连接ID,以备将来使用。
连接响应:
偏移量大小名称值 0 32位整数操作0 //连接 4 32位整数transaction_id 8 64位整数connection_id 16
- 选择一个随机的交易ID。
- 填写公告请求结构。
- 发送数据包。
IPv4声明请求:
偏移量大小名称值 0 64位整数connection_id 8 32位整数action 1 // //宣布 12 32位整数transaction_id 16 20 位字符串info_hash 36 20位字符串peer_id 56 64位整数已下载 64 64位整数左 72个64位整数上载 80个32位整数事件0 // 0:无; 1:完成;2:开始;3:停止 84 32位整数IP地址0 //默认值 88 32位整数键 92 32位整数num_want -1 //默认值 96 16位整数端口 98
- 接收数据包。
- 检查数据包是否至少为20个字节。
- 检查交易ID是否等于您选择的ID。
- 检查动作是否宣布。
- 在间隔秒过去或发生事件之前,请勿再次声明。
请注意,大多数跟踪器仅会在有限的情况下接受IP地址字段。
IPv4宣布响应:
偏移量大小名称值 0 32位整数操作1 //宣布 4 32位整数transaction_id 8 32位整数间隔 12 32位整数leechers 16 32位整数seeder 20 + 6 * n 32位整数IP地址 24 + 6 * n 16位整数TCP端口 20 + 6 * N
IPv6公告具有与v4相同的结构,包括所使用的操作号,但响应中<IP地址,TCP端口>对的跨度为18个字节,而不是6个。
这意味着请求中的IP地址字段保持32位宽,这使得该字段在IPv6下不可用,因此应始终设置为0。
使用哪种格式由基础UDP数据包的地址族确定。即,来自v4地址的数据包使用v4格式,来自v6地址的数据包使用v6格式。
将主机名解析为v4和v6然后向两者通告的客户端应为两者使用相同的密钥,以便关心准确统计信息保留的跟踪器可以将这两个通告匹配。
一次最多可以刮掉大约74个种子。此协议无法完全解决。
- 选择一个随机的交易ID。
- 填写抓取请求结构。
- 发送数据包。
抓取要求:
偏移大小名称值 0 64位整数connection_id 8 32位整数action 2 //刮取 12 32位整数transaction_id 16 + 20 * n 20字节字符串info_hash 16 + 20 * N
- 接收数据包。
- 检查数据包是否至少为8个字节。
- 检查交易ID是否等于您选择的ID。
- 检查动作是否被刮擦。
刮刮反应:
偏移量大小名称值 0 32位整数操作2 //刮取 4 32位整数transaction_id 8 + 12 * n 32位整数播种器 12 + 12 * n 32位整数完成 16 + 12 * n 32位整数leechers 8 + 12 * N
如果跟踪器遇到错误,则可能会发送错误数据包。
- 接收数据包。
- 检查数据包是否至少为8个字节。
- 检查交易ID是否等于您选择的ID。
错误响应:
偏移量大小名称值 0 32位整数操作3 //错误 4 32位整数transaction_id 8字符串消息
Azureus,libtorrent [2],opentracker [3],XBT Client和XBT Tracker支持此协议。
不包括扩展位或版本字段。客户端和跟踪器不应假定数据包具有一定大小。这样,可以在不破坏兼容性的情况下添加其他字段。
有关扩展协商协议,请参见BEP 41 [4]。