原贴地址:https://blog.csdn.net/djl806943371/article/details/89683607
首先理解BitTorrent的大致机制,是允许客户端之间相互请求下载大文件。大文件被拆分成小片,当有客户端从其他客户端下载了一个文件是,他会告诉其他客户端,他也有这个文件了,这样其他客户端也可以来他这里下载这个文件。这一些客户端被称为一个集群。
那么我们需要知道一个客户端是如何加入和离开集群的。加入一个集群是通过下载一个torrent文件实现的,这个torrent问价会告诉客户端这个文件有多大,包含多少片,如何去跟集群中其他客户端建立连接。在过去,一个集群中存在一个tracker,记录集群中有哪些客户端,当有新的客户端加入时,他会将其他客户端的信息告知,然后客户端之间通过TCP连接进行数据交换。客户端一次可以建立100个TCP连接。在二十世纪初,由于tracker会被其他客户端过于关注,人们开始使用无追踪的torrents。这些torrent可以与一个host取得联系,host会告诉他们如何加入DHT(distributed hash table)。DHT提供了哈希值与节点之间的映射关系。在这种关系中,即使节点改变了很多设置,集群内的客户端仍然可以找到这个节点。 与之前的集中化管理的tracker不同,映射被分布式地存储在每一个host中。
BitTorrent将文件拆分为很多片,每片大小为256KB-1MB,这个大小可以使拥塞窗口增长到足够大以提供较高的传输速率。同时每一片还会被拆分成更小的片。这样就可以从更多的客户端请求文件,降低下载时间。除此之外,我们还要对文件完整性进行验证,使用SHA1,这是一种加密哈希功能,为每个文件片创建一个独有的哈希值,以验证文件完整性,当文件SHA1值不匹配时会被丢弃并尝试重新请求下载。现代BitTorrent中,会将多次提供错误文件的host加入黑名单。
传输过程中,会尝试下载文件在集群中最稀有的片。只有一种例外情况,就是当文件的绝大部分已经下载完成了,这是会对剩余的片向多个客户端进行请求,当接收到重复文件可以进行丢弃,这样可以避免一个速度比较慢的节点影响整体的下载速度。
在请求文件时,为了避免建立好多连接但是速度都很慢的情况,你发送数据时会尽可能发送给也发送给你数据的host,也就是谁给你发送过数据,你才会给他发送数据。实现这一功能是通过choking的方式,集群中大部分host处于choke状态,你不会向他们发送数据。BitTorrent会监测你从每个host下载的速度,选取其中速度最快的几个,通常只有4个或者集群中host数量的开根号个。同时,每隔30s左右,BitTorrent会unchoke所有host,让你尝试给所有人发送数据,然后根据传输速度,重新选取速度最快的。这一算法我们成为tit-for-tat(针锋相对)算法。