[趣谈网络协议学习] 17 P2P协议:我下小电影, 99%急死你

FTP 的两种工作模式

FTP, 也即⽂件传输协议:FTP 采用两个 TCP 连接来传输一个文件:控制连接、数据连接。

从 FTP 服务器角度,FTP 有两种工作模式,分别是主动模式(PORT)和被动模式(PASV)

  • 主动模式(PORT):客户端打开N和N+1两个端口(N>1024),N端口向服务器的命令端口 21 发起连接,N+1 端口监听,并向服务器发出 “port N+1” 命令,服务器从自己的数据端口 20,主动连接到客户端指定的数据端口 N+1。
  • 被动模式(PASV):客户端打开N和N+1两个端口(N>1024),N端口连接服务器的 21 端口,提交 PASV 命令,服务器会开启一个任意的端口 P(> 1024),返回“227 entering passive mode”消息里面包含FTP 服务器开放的用来进行数据传输的端口。客户端收到消息取得端口号之后,会通过 N+1 号端口连接服务器的端口 P,然后在两个端口之间进行数据传输。

难以解决单一服务器的带宽压力, 因为使用的是传统的客户端服务器的方式。

P2P 是什么?

P2P就是peer-to-peer。资源并不集中地存储在某些设备上,而是分散地存储在多台设备上。这些设备姑且称为 peer。

下载文件时,需得到下载文件的peer,与之建立点对点连接,就近下载文件。下载文件后,自己成为peer的一员。

种子(.torrent)文件

通过种子,即.torrent文件,知道哪些peer有什么文件。

.torrent文件组成:announce(tracker URL)文件信息

文件信息

  • info 区:指定的该种子有几个文件、文件有多长、目录结构,以及目录和文件的名字。
  • Name 字段:指定顶层目录名字。
  • 每个段的大小:BitTorrent(简称 BT)协议把一个文件分成很多个小段,然后分段下载。
  • 段哈希值:将整个种子中,每个段的 SHA-1 哈希值拼在一起。

下载过程

  1. BT 客户端解析.torrent 文件,得到 tracker 地址,然后连接 tracker 服务器
    racker 服务器
  2. 回应下载者的请求,将其他下载者(包括发布者)的 IP 提供给下载者
  3. 下载者再连接其他下载者,根据.torrent 文件,两者分别对方告知自己已经有的块,然后交换对方没有的数据。
  4. 下载者计算下载的每个块的Hash值,并与.torrent 文件中的对比。不一样则需要重新下载这个块

这种方式特别依赖 tracker。racker服务器登记有哪些应用请求哪些资源,一旦出现故障,BT工具无法工作。

去中心化网络(DHT)

为了彻底非中心,就有了一种叫作DHT(Distributed Hash Table)的去中心化网络。每个加入这个 DHT 网络的人,都要负责存储这个网络里的资源信息和其他成员的联系信息。一种著名的 DHT 协议,叫Kademlia 协议。

Kademlia 协议

可参看 :Kademlia

任何一个 BitTorrent 启动之后,它都有两个角色。一个是peer,另一个角色DHT node。

  • peer:监听一个 TCP 端口,用来上传和下载文件。
  • DHT node:监听一个 UDP 的端口,通过这个角色,这个节点加入了一个 DHT 的网络。

DHT网络
在 DHT 网络里面,每一个 DHT node 都有一个 ID。每个 DHT node 都有责任掌握一些知识,也就是文件索引,知道某些文件是保存在哪些节点上,本身不一定就是保存这个文件的节点。

哈希值

每个 DHT node 不会有全局的知识,不知道所有的文件保存在哪里,只需要知道一部分。

DHT node 上应该有哪些文件的位置信息?
每个文件可以计算出一个哈希值,而DHT node 的 ID 是和哈希值相同长度的串。

DHT 算法是这样规定的:如果一个文件计算出一个哈希值,则和这个哈希值一样的那个 DHT node,就有责任知道从哪里下载这个文件,即便它自己没保存这个文件。除了一模一样的那个 DHT node 应该知道,ID 和这个哈希值非常接近的 N 个 DHT node 也应该知道。

例子如上面的图: 文件 1 通过哈希运算,得到匹配 ID 的 DHT node 为 node C,node C 有责任知道文件 1 的存放地址,虽然 node C 本身没有存放文件 1。文件 2 通过哈希运算,得到匹配 ID 的 DHT node 为 node E,node D 和 E 的 ID 值很近,所以 node D 也知道。

新的节点 node new 如果想下载文件 1,它首先要加入 DHT 网络。

新的节点 node new如何加入DHT 网络

种子.torrent中保存的不再是tracker的地址,而是一个node地址的list(去中心化),只要与其中一个联系上便加入了网络。

新的节点 node new如何下载文件 1

node new 会计算文件 1 的哈希值,根据这个哈希值了解到哪些node知道从哪可以下载到这个文件。例如计算出来的哈希值就是 node C。

node new但是如何联系node C?

种子里面的 node 列表里面很可能没有 node C,但是它可以它能联系上的 node 问,node new 想联系 node C,就去像去万能的朋友圈问,并且求转发,朋友再问朋友,很快就能找到。如果找不到 C,也能找到和 C 的 ID 很像的节点,它们也知道如何下载文件 1。

在 node C 上,告诉 node new,下载文件 1,要去 B、D、 F,于是 node new 选择和 node B 进行 peer 连接,开始下载,它一旦开始下载,自己本地也有文件 1 了,于是 node new 告诉 node C 以及和 node C 的 ID 很像的那些节点,我也有文件 1 了,可以加入那个文件拥有者列表了。

DHT node ID 以及文件哈希是个什么东西?

节点 ID 是一个随机选择的 160bits(20 字节)空间,文件的哈希也使用这样的 160bits 空间。

所谓 ID 相似,具体到什么程度算相似?

在 Kademlia 网络中,距离是通过异或(XOR)计算的。例如01010 与 01000 的距离,就是两个 ID 之间的异或值,为 00010,也即为 2。 01010 与 00010 的距离为 01000,也即为 8。

高位不同的,表示距离更远一些;低位不同的,表示距离更近一些,总的距离为所有的不同的位的距离之和。

这个距离不能比喻为地理位置,因为在 Kademlia 网络中,位置近不算近,ID 近才算近。

DHT 网络中的朋友圈是怎么维护的?

按距离分层。对于某个基础节点node,将与之从倒数第 i 位开始不同的节点放入“k-bucket i”,k-bucket i 内只有 2 i + 1 2^{i+1} 个节点,与node的距离范围为 [ 2 ( i 1 ) , 2 i ) [2^{(i-1)}, 2^i)

DHT 网络是如何查找朋友的?

node A 要找 node B,两者异或距离为10110,范围在 [ 2 4 , 2 5 ) [2^4, 2^5) , 所以 node B 可能在 node A 的 ”k-bucket 5“中,两者从第5位开始不同。

A 发现自己的 k-bucket 5 中没有 B,于是在 k-bucket 5 中随便找了一个,假如是C,既然 C 与 A 的第5位不同,那么肯定与 B 的第5位相同,即 C 与 B 的距离 < 2 4 < 2^4 ,距离缩短了一半以上。C 再继续查找即可,时间复杂度位 l o g ( n ) log(n)

在 DHT 网络中,朋友之间怎么沟通呢?

Kademlia 算法中,每个节点只有 4 个指令。

  • PING:测试一个节点是否在线
  • STORE:要求一个节点存储一份数据,既然加入了组织,有义务保存一份数据。
  • FIND_NODE:根据节点 ID 查找一个节点
  • FIND_VALUE:根据 KEY 查找一个数据,实则上跟 FIND_NODE 非常类似。

DHT 网络中,朋友圈如何更新呢?

  • 每个 bucket 里的节点,都按最后一次接触的时间倒序排列。
  • 每次执行四个指令中的任意一个都会触发更新。
  • 当一个新节点与自己接触时,如果在 k-bucket 中,则置顶;不在,若通讯录满,最旧的节点能 PING 通,则丢弃新节点;PING 不同,则删除旧节点,加入新节点。

参考资料:

趣谈网络协议(极客时间)链接:
http://gk.link/a/106nW

Kademlia:
https://zh.wikipedia.org/wiki/Kademlia
https://en.wikipedia.org/wiki/Kademlia

P2P之Kademlia (一):
https://blog.csdn.net/cz_hyf/article/details/5076988

P2P之Kademlia (二):
https://blog.csdn.net/cz_hyf/article/details/5178330


GitHub链接:
https://github.com/lichangke/LeetCode
知乎个人首页:
https://www.zhihu.com/people/lichangke/
CSDN首页:
https://me.csdn.net/leacock1991
欢迎大家来一起交流学习

发布了170 篇原创文章 · 获赞 16 · 访问量 2834

猜你喜欢

转载自blog.csdn.net/leacock1991/article/details/100832562