我对 KaZaA 的理解
渊源
KaZaA 是一个基于 FastTrack 协议 的应用
FastTrack 协议是 Gnutella 的拓展,加入了 “超级节点”的概念
在 Gnutella 中,对文件的查询,直接使用洪泛,在邻居节点上迭代,使用 TTL 限制广播长度
而 FastTrack 中,只有超级节点可以洪泛,普通节点只有上传下载的的基本功能
细节
普通节点A 会维护一个“超级节点”列表,当有文件需求时,将试图连接一个“超级节点”
连接好后,普通节点会向超级节点请求该文件
“超级节点”查询自身并向与之连接的“超级节点”查询,引发洪泛查询
查到该文件,则向查询者A返回该文件的位置(某个节点B)
A与B 进行连接,下载文件
当一个节点C加入到网络时,会向超级节点(父节点)报告自己所分享的文件,超级节点会更新索引列表
节点C会根据自己的性能,标记自己为“普通节点”或 “超级节点”
如果C标记为“超级节点”,肯定要向周围的超级节点发送“更新信息”
至于节点C如何发现“超级节点”,可能是通过局域网广播搞的,可以看看实现(1)
当前网络没有“超级节点”时,直接在普通节点上洪泛。(我没有实现这一点)
编程思路:
p2p 是去中心化的,所以每个节点都应当准备成为“超级节点”
Node 应当具备的数据结构:
flag {标记自己是否超级}
超级节点列表(若为普通节点,该列表都是父节点)
文件索引列表 {文件标识码=>位置}// 只有“超级节点”需要
超级Node 维护的进程:
1. 监听“文件查询请求”//来自某个普通节点
2. 监听“新节点加入请求”
3. 监听 “新文件请求”
4. 监听 “广播查询请求”//来自某个超级节点
普通Node 维护的进程:
1. 监听文件下载请求
2. 监听文件查询响应
3. 监听重置计时器请求
新节点加入的实现
新节点向局域网发送“我来了”,的广播
超级Node的2进程收到后,立即向他返回自己的地址
新节点把收到的第一个和第二个信息的源作为自己的“父节点”,加入到自己的“超级节点列表”中
新节点将自己分享的文件 hash 码上传给“父节点”
超级Node 的3进程收到文件hash,更新自己文件索引列表文件查询的实现
节点依次向父节点发送连接请求,直到连接成功
设超级Node A 的1 进程收到要查询的hash,查询本地文件索引列表,若发现,则返回“成功”状态码,并返回文件位置
若没找到,返回一个“查询中”状态码,超级Node A 向查询者发送“重置计时器”请求(异步), 向其他向超级节点4进程查询(异步),附带查询者的ip(ip_a),如果有某个超级节点 D 查到了该文件,立即向 ip_a 的进程 2 发送响应信息
查询者的计时器超时,则查询失败文件下载
普通节点在计时器超时之前收到了某个超级节点的回应,并附带目标文件的地址(ip_has)
直接向ip_has 请求该文件,并下载