bt协议详解 基础篇(下)
bt协议详解 基础篇(下)
最近开发了一个免费教程的网站,产生了仔细了解bt协议的想法,所以写了这一篇文章,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的技术,敬请期待。
1 简介
bt是BitTorrent协议的简称,bt协议是最流行的p2p下载协议,另外一种比较流行的p2p下载协议叫ed2k,ed2k的全称叫eDonkey2000 network,这里我们只讨论bt协议,ed2k协议以后有机会再和大家分享。
相信很多人都听说过bt协议。但是当我问周围的人究竟什么是bt协议呢?他们的解释让我对bt协议的理解变得更含糊,为了弄清楚心中的问题,我开始了自己对bt协议的学习。
我在官网 上找到一篇文章The BitTorrent Protocol Specification。这个标题翻译过来就是“bittorrent协议规范”,是bittorrent协议的基础篇,为什么说是基础篇呢?
BT协议是一个协议簇。
有点像tcp/ip协议一样,bt协议不是一个简单的协议,而是一系列相关的协议组成的,而且这个协议簇一直在进化。
既然这篇文章的主题是“基础篇”,所以它的内容主要来自bep_0003,也就是bittorrent协议规范,因为其它的协议都是以这个协议为基础的,可见这个的重要性。
接上篇。
peer protocol
bt peer协议是基于tcp或者utp协议(utp协议也是bt协议簇中的一个,后面会专门写一篇关于utp协议的文章)。
peer连接是对称的,双方可以同时发送数据,而且数据的形式是一样的。一个peer代表一个bt下载用户。
peer协议会使用torrent文件中的pieces块(文件块,前面有讲到),下标从0开始。当一个peer下载完一个文件块,检查文件块的hash值匹配正确的时候,它就发送一个announce请求给拥有该piece块的peer列表,声明自己拥有该piece块,这样其它的peer就可以向这个peer发送下载该piece的请求。
peer链接两端包含2位的状态:choked,unchoked和interested,uninterested。Choking表示不会发送数据知道一个unchoking动作发生。后面将会解释为什么会存在choking这个状态。
当peer连接的双方有一个是interested状态,而且另外一个不是choking状态,这个连接就可以进行数据传输。无论何时当一个下载者向一个unchoked状态的peer发送下载请求时,interest状态必须每次更新 。这个属性的实现比较困难,但是这让下载者知道当它是unchoked的状态时哪些peers将会立刻开始下载成为可能。
peer连接一开始是choked和uninterested状态。
当数据开始传输时下载者必须把下载块放进请求队列来获取更高的tcp性能(这就是所谓的管道技术)。另一方面,不能马上写入tcp缓存的请求必须放进队列,而不是放在应用层的网络缓冲区,这样当choke动作发生时,他们才能被丢掉。
peer连线协议由握手和紧跟着的无穷的用长度做前缀的字符串流。握手由19(十进制字符串)跟着字符串'BitTorrent protocol'开始。开始的字符串是长度。
后面所有的整数都是使用4字节big-endian(高字节序)
固定的头部之后跟着是8个保留字节,在目实现的协议版本中值都是0。如果你想扩展协议,可以使用这8个字节,请和Bram Cohen(bt协议的作者)联系确保所有扩展的兼容性。
再接下来是20个字节的sha1哈希值,来自torrent文件中的info字段。如果peer连接的两端发送的哈希值不一致,则连接被关闭。一个例外的情形是当一个下载者想在一个端口开始多线程下载,他们等待进来的连接发送hash,如果这个hash在它的维护的列表里面,就把这个hash返回给另一端。
20字节hash的后面是20字节的peer id,这个id会发送给bt tracker服务器,而且会出现在bt tracker返回的peer列表里面。
上面就是一次握手所有的内容。接下来是可选一系类的长度做前缀的消息。长度为0表示keepalives(保持连接),被忽略。保持连接消息每两分钟发送一次。
peer messages
所有的非保持连接的消息由一个表示类型的字节开始。
类型列表如下:
- 0 - choke
- 1 - unchoke
- 2 - interested
- 3 - not interested
- 4 - have
- 5 - bitfield
- 6 - reques5t
- 7 - piece
- 8 - cancel
'choke', 'unchoke', 'interested', 和 'not interested' 这四个消息没有消息体。
bitfield消息只作为第一个消息发送一次。它的消息体是一个bitfield数据类型(参考c语言),下载者发送过的块的下标对应的位置1,其余的置0。下载者没有任何内容的时候可以跳过bitfield消息。bitfield的第一个字节对应下标0 - 7,第二个对应 8 - 15,等等。多余的位置0。
have消息的消息体是一个数字,表示下载者最近下载完成和检验正确的文件块的下标。
request消息包含index、begin、length三个字段。最后两个是字节偏移。length通常是2的指数除非是文件的最后一块。当前所有bt协议的实现版本中length的值是16kiB,关闭连接的request中length字段的值要大于16kiB。
cancel消息和request有一样的消息体。用来取消下载某一个文件块。
piece消息包含index、begin、piece字段。它们的值和request消息是相关的。
下载者通常用随机的顺序下载文件块,这样能提高效率。
choking发生的原因有几个。一个是当一次发起过多的连接时tcp拥塞控制表现极差。另外choking可以让peer连接的双方使用 tit-for-tat-ish算法来保证下载速度的一致。
一个好的choking算法必须具备几个好的特性。它应该能控制并发数量来获取更高的tcp性能。它应该避免过快的choking和unchoking。最后它应该每过一段时间就尝试空闲连接来找到更好的连接,这就是所谓的unchoking优化。
本文来自 免费教程网
bt协议详解 基础篇(下)的更多相关文章
- bt协议详解 基础篇(上)
bt协议详解 基础篇(上) 最近开发了一个免费教程的网站,产生了仔细了解bt协议的想法,所以写了这一篇文章,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的技术,敬请期待. 1 ...
- bt协议详解 DHT篇(下)
bt协议详解 DHT篇(下) 最近开发了一个免费教程的网站,产生了仔细了解bt协议的想法,这篇文章是bt协议详解系列的第三篇,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的技术 ...
- bt协议详解 DHT篇(上)
bt协议详解 DHT篇(上) 最近开发了一个免费教程的网站,突然产生了仔细了解bt协议的想法,这篇文章是bt协议详解系列的第三篇,后续还会写一些关于搜索和索引的东西,都是在开发这个网站的过程中学习到的 ...
- http协议详解-经典篇
本文转载至 http://www.cnblogs.com/flychen/archive/2012/11/28/2792206.html ————————————————————————————— ...
- 入木三分学网络第一篇--VRRP协议详解第一篇(转)
因为keepalived使用了VRRP协议,所有有必要熟悉一下. 虚拟路由冗余协议(Virtual Router Redundancy Protocol,简称VRRP)是解决局域网中配置静态网关时,静 ...
- iOS开发 - OC - block的详解 - 基础篇
深入理解oc中的block 苹果在Mac OS X10.6 和iOS 4之后引入了block语法.这一举动对于许多OC使用者的编码风格改变很大.就我本人而言,感觉block用起来还是很爽的,但一直以来 ...
- 网络协议之bt---bt协议详解 DHT篇(下)
-------------------------author:pkf -------------------------------qq:1327706646 ------------------- ...
- HTTP协议详解-基础知识
HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.绝大多数的Web开发,都是构建在HTTP协议之上的Web应用. HTTP协议的主要特点可概括如下: 简单: ...
- MySql-Binlog协议详解
Reference: https://blog.csdn.net/hj7jay/article/details/56665057?utm_source=blogxgwz7 MySql-Binlog协议 ...
随机推荐
- 第十章 Secret & Configmap(下)
10.4 ConfigMap Secret可以为Pod提供密码.Token.私钥等敏感数据:对于一些非敏感数据,比如一些配置信息,则可以用ConfigMap. configMap的使用方式与Secre ...
- kubectl get pods The connection to the server was refused - did you specify the rig
1 主要是运行这个命令 alias kubectl='kubectl --kubeconfig=/etc/kubernetes/kubelet.conf'问题解决. 同时也用到如下命令: pas ...
- MySql——编程
基本语法形式 语句块模式: 在mysql编程中,begin....end;基本代替了原来编程语句中的{...}语法. 但又有所区别: 一个bigin...end;块,可以给定一个“标识符”,并且可以使 ...
- 第七章 : Git 介绍 (上)[Learn Android Studio 汉化教程]
Learn Android Studio 汉化教程 [翻译]Git介绍 Git版本控制系统(VCS)快速成为Android应用程序开发以及常规的软件编程领域内的事实标准.有别于需要中心服务器支持的早期 ...
- 2019 最新 阿里天猫、蚂蚁、钉钉ava 面试题汇总,附答案
Java面试前需要做足各方面的准备工作,肯定都会浏览大量的面试题,本人也不例外,这是一些最新面试题,分享给大家. Java基础 面向对象的特征:继承.封装和多态 int 和 Integer 有什么区别 ...
- Tkinter画布-Canvas
Python - Tkinter画布-Canvas: Canvas是一个长方形的面积,图画或其他复杂的布局.可以放置在画布上的图形,文字,部件,或是帧 Canvas是一个长方形的面积,图画或其他复杂的 ...
- [BZOJ][CQOI2014]数三角形
Description 给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个.下图为4x4的网格上的一个三角形. 注意三角形的三点不能共线. Input 输入一行,包含两个空格分隔的正整数m和 ...
- freebsd静态路由
FreeBSD下增进静态路由的行动 1.手工添加 # route add -net 192.168.2.0/24 192.168.1.2 2. 通过rc.conf永世 设置 # Add static ...
- 一个不明觉厉的貌似包含很多linux资料索引的网页
http://man.lupaworld.com/content/other/Linux/linuxmanage/node108.html 貌似是个官方的doc之类的...
- 开始使⽤ZooKeeper的API
在之前的章节中,我们使用zkCli工具介绍了ZooKeeper的基本操作.从本章开始,我们将会看到在应用中如何通过API来进行操作.首先介绍一下如何使用ZooKeeper的API进行开发,展示如何创建 ...