DHT协议代码分析篇

DHT协议代码分析篇

背景

上一章节主要讲解了dht协议理论原理篇, 现在聚焦到具体分析开源代码, 加深对处理流程的理解。

主要对开源代码 https://github.com/shiyanhui/dht做分析理解

讲解核心流程,作为client客户端

作为客户端, 我会发起 ping, find_node, get_peers, announce_peer 四种请求, 当收到回应后, 我会做相应的处理。

ping

什么时候客户端发起ping请求

本地队列有更新时

ping请求会返回什么结果和做什么逻辑处理?

成功不做处理, 失败则加入黑名单, 并在本地分布式队列中删除掉

find_node

根据节点hash, 去找节点对应的ip:port

客户端传参:

  • id: 当前node_id
  • target: 目标node_id

什么时候客户端发起find_node请求?

  • 作为新节点的时候, 需要加入到网络时
  • 客户端接收到find_node的回应时,需要重新发起find_node请求, 主要是需要增加自己的朋友圈人数
  • 在刷新操作时,需要对bucket中前8个node,重新find_node请求, 验证其是否有效

find_node请求,会返回什么结果和做什么逻辑处理?

返回要查找的target 和 一组node列表

  • 将这组node插入到本地routingTable hash表中
  • 如果找到了目标target,则提前返回
  • 如果没有找到目标target, 则在本地邻居中找到距离target最近的k个体node, 并对此k个node,发起find_node请求

get_peers

根据文件hash, 去问对应node,是否知道此文件

客户端传参:

  • id: 当前node_id
  • info_hash: 要查询的文件hash

什么时候客户端发起get_perrs请求?

  • 要真实下载文件的时候,我先去这个网络,问下这个文件hash谁知道
  • 客户端接收到get_peers的回应时, 如果回应失败,则需要重新发起get_peers请求

get_peers请求,会返回什么结果和做什么逻辑处理?

  • 返回一组<info_hash, value_list>列表, 如果列表不为空,插入本地的peer map中
  • 如果列表为空,则继续发起get_peers请求

announce_peer

客户端传参

  • id: 当前node_id
  • info_hash: 要广播的文件hash
  • implied_port: 内部端口
  • port: 端口
  • token: //server端生成的随机数

  • 本地下载文件成功后, 则广播告知, 我下载文件成功了, 即我存储文件hash

**announce_peer 会返回什么结果和做什么逻辑处理? **

  • 不做其他逻辑处理

在客户端相应结束前, 执行本地hash表插入操作

讲解核心流程,作为server客户端

ping

收到客户端发起的ping请求, server端会做什么逻辑处理?

直接会将server 的id返回, 不做其他逻辑处理

find_node

收到客户端发起的find_node请求, server端会做什么逻辑处理?

  • 先去本地hash表,是否存在想要的target节点信息
  • 如果有, 则直接返回
  • 如果没有, 则找距离target最近的k个node节点

get_peers

收到客户端发起的find_node请求, server端会做什么逻辑处理?

  • 先去<info_hash: peer节点列表> hash表中,判断是否存在知道info_hash的peer列表
  • 如果存在, 则返回, 并且记录<请求方ip,生成token随机数>,并返回生成的token随机数
  • 如果不存在,则找距离info_hash最近的k个node节点

announce_peer

收到客户端发起的announce_peer请求, server端会做什么逻辑处理?

  • 检查token是否匹配<请求房ip, 生成token随机数>map, 如果不匹配,则不做处理,这里限制token的有效性
  • 将传参中的<info_hash, port, token>作为基础信息peer,存入<info_hash, peer节点列表>中

公共篇

涉及到几个client,server共享数据结构体:

  • routingTable : 分布式路由hash存储, 即上一章讲的, 将不同朋友分类,放到不同的桶中, 但为了节约空间, 这里会存在桶的动态分裂, 后续有时间再将
  • peersManager: 管理<info_hash, 知道文件的node列表>
  • tokenManager: announce_peer时,对没有记录的token做过滤操作
  • blackList: 一些ping不通的node节点, 加入黑名单
  • workerTokens: 限制并发

总结

这里从client,server端的角度, 讲解他们的主要工作任务。 更加帮助我们深入理解dht通信流程。

参考文章:

https://github.com/shiyanhui/dht