论坛首页 综合技术论坛

信p2p者,得永生(一)

浏览 18467 次
该帖已经被评为良好帖
作者 正文
   发表时间:2009-08-11  

开篇

    此文章的题目来自于当下的两哥之争,本意有调侃之意,但是用在本文,却无此意,我以十分真诚并且后知后觉的态度认定,p2p是未来的主要计算模型。尤其是在视频音频领域,但是将来,p2p一定会拓展到普通的计算上。

    要解释清楚这个问题,我们得从当下最流行的音频视频p2p软件聊起。先来说说较为简单的一个音频p2p软件,酷狗。

    酷狗的原型应该是来自于一个国外的公司,名字我已忘记,那家公司也是通过mp3的p2p下载作为主要业务,不过可惜的是在美国mp3因为版权问题非常严重,所以那家公司的最终结局只有一个,就是关门。

    但是在中国就不一样了,版权问题没有这么严重,或者说相当的不严重,所以酷狗活得很好。这就是国情啊(理论上来讲,酷狗应该也有一些版权问题,可能跟版权商有合作关系,不过大多数的音频应该没有版权问题,这种情况和视频网站是类似的)。

    下面让我们来看看酷狗的技术实现。以下都是ahuaxuan的猜测,供大家讨论,未必完全正确,也未必完全错误,拿出来和大家探讨。

    酷狗应该是采用中心的目录服务器结构来实现p2p的功能,也就是说,所有的音频文件的基本信息都会注册到酷狗的中心目录服务器上,那么酷狗的客户端需要下 载某个视频的时候,则从中心目录服务器上查找,找到相信的音频信息,每个音频信息都会对应一堆地址,这些地址是其他的拥有该音频的客户端ip。让我们用一 张图来描述一下这个问题:


这样我们就可以虚拟一个流程出来:
1.1号客户端请求中心目录下载服务器,要求下载“”。
2.  中心目录服务器通过搜索引擎分词,查询之后,得到一堆id。
3.  中心目录服务器根据id查找id对应的ip。显然一个id拥有多个ip,是1:n的关系。
    (很不巧,这首歌2,3号客户机上都有, 当然这里并不是应该返回所有的ip地址,而是应选择最短路径的地址返回。让我们来怀念一下dijikstra。
4.  中心目录服务器返回音频文件的ip列表。
5.  1号客户机得到两个ip地址,然后分别2号机请求音频的第一段,从3号机请求音频的第二段。即多地址多线程分段下载。
6.  1号机下载完成之后通知中心目录服务器,这样中心目录服务器关于这个视频又多了一个ip地址供其他客户端下载。


这个应该是最概要的流程,接着可以在这个流程上细化。

从上图我们可以看到,任何一个客户机既是client,又是server。作为client,它从其他server上下载数据,作为server,它提供数据给其他client下载。

    所以当我们开着酷狗听歌的时候,其实你的机器就变成了下载服务器了,同样,如果你用的是迅雷,而且一直不把迅雷关掉,那么你的机器就成为专职的下载服务器了。

    看到这里,我们有理由相信,如果掌握了下列技术,做一个酷狗不是什么难事,括号后面是ahuaxuan的选型。

1.    搜索技术(lucene)-服务器端
2.    音频管理系统(java,同时涉及到缓存和数据库系统)-服务器端
3.    客户端ui编程(最好是mfc之流)-客户端
4.    下载服务器(c,对windows的io比较熟悉)-客户端

正如前面所说,这个只是非常高层次的设计,而且对于有过大型网站系统经验的人来说,1,2点是没有问题的。然后3,4点需要对c/c++比较熟悉的人来做,当然btcomet据说是python写的。所以我也在思考python+c实现客户端的可行性。


    上面讲到的是基本的整个软件的结构体系,或者称为“架构“,在high level层面还有一个问题,就是协议的问题,客户端之间相互下载应该使用说明协议,以及客户端和服务器端的交互应该使用什么协议,目前ahuaxuan 选择的是bt协议。利用成熟的协议可以减少很多的工作量。或者电驴的协议应该也不错,不过没有深入研究过。


大家一起来拍砖。

   发表时间:2009-08-12  
客户端处于内网怎么办?另外的人是不能直接连接处于内网的服务器的,这个时候,我觉得可以使用UDP穿透内网。
也就是说客户端向中心服务器注册,中心服务器此时就知道了当前客户端所打开的UDP端口,这个端口是别人客户端也可以访问的。就像QQ传文件有时候用UDP,有时候用TCP一样,如果是外网,那TCP当然最好了,如果是内网,就只能用这种先注册,然后再使用的UDP的方式。
所以中心服务器要记的不仅仅是每个客户端的IP地址,还记录他们是处于外网还是内网,如果是内网的话,还要记录每个客户端所打开的UDP的映射端口。这样这个客户端才有可能成为一个服务器,让别人来访问。
2 请登录后投票
   发表时间:2009-08-12  
java.lang.Object 写道
客户端处于内网怎么办?另外的人是不能直接连接处于内网的服务器的,这个时候,我觉得可以使用UDP穿透内网。
也就是说客户端向中心服务器注册,中心服务器此时就知道了当前客户端所打开的UDP端口,这个端口是别人客户端也可以访问的。就像QQ传文件有时候用UDP,有时候用TCP一样,如果是外网,那TCP当然最好了,如果是内网,就只能用这种先注册,然后再使用的UDP的方式。
所以中心服务器要记的不仅仅是每个客户端的IP地址,还记录他们是处于外网还是内网,如果是内网的话,还要记录每个客户端所打开的UDP的映射端口。这样这个客户端才有可能成为一个服务器,让别人来访问。

恩,是的,上网找到一个python使用udp穿透的例子,先研究研究。

中心服务器需要记录的内容还是挺多的,我现在不太明白的是btcomet是怎么做的,其实酷狗的做法应该也是类似的。
0 请登录后投票
   发表时间:2009-08-12  
你有兴趣做类似的东西么,有兴趣的话,叫上我哦。
0 请登录后投票
   发表时间:2009-08-12  
前年做过一个类似飞鸽的东西,在局域网用来传文件的,不需要登录,只要启动以后,就会自动加入一个组播组,用组播实现局域网内的互相通知。然后基于UDP来发送消息。基于TCP来收发文件,也做了一个基于UDP的发送文件功能。由于UDP是不可靠的,重新组装包的顺序以及请求重发包的逻辑搞了挺久的。
当时想做一个UDP注册到中心服务器上,然后就可以全网UDP和TCP都能传文件了,但是当时没有外网的服务器一直都没有做成。
0 请登录后投票
   发表时间:2009-08-12   最后修改:2009-08-12
java.lang.Object 写道
前年做过一个类似飞鸽的东西,在局域网用来传文件的,不需要登录,只要启动以后,就会自动加入一个组播组,用组播实现局域网内的互相通知。然后基于UDP来发送消息。基于TCP来收发文件,也做了一个基于UDP的发送文件功能。由于UDP是不可靠的,重新组装包的顺序以及请求重发包的逻辑搞了挺久的。
当时想做一个UDP注册到中心服务器上,然后就可以全网UDP和TCP都能传文件了,但是当时没有外网的服务器一直都没有做成。

这个东西我也做过,这个主要是多播,然后就是tcp发文件。我用python写的,当时还是命令行的方式搞的。

附上之前找到的python做利用stunb做udp的穿透的代码
0 请登录后投票
   发表时间:2009-08-13   最后修改:2009-08-15
内网用UDP穿透也有局限,用 ISA200x 做内网出口的一般都只开放了HTTP的80端口和HTTPS的443端口,对于这样的环境UDP就无能为力了。
用 Python 的话 ntlmaps 可以做 NTLM 的代理。
或者在代码里面视具体的网络情况选择一种合适的代理方式了。



java.lang.Object 写道
客户端处于内网怎么办?另外的人是不能直接连接处于内网的服务器的,这个时候,我觉得可以使用UDP穿透内网。
也就是说客户端向中心服务器注册,中心服务器此时就知道了当前客户端所打开的UDP端口,这个端口是别人客户端也可以访问的。就像QQ传文件有时候用UDP,有时候用TCP一样,如果是外网,那TCP当然最好了,如果是内网,就只能用这种先注册,然后再使用的UDP的方式。
所以中心服务器要记的不仅仅是每个客户端的IP地址,还记录他们是处于外网还是内网,如果是内网的话,还要记录每个客户端所打开的UDP的映射端口。这样这个客户端才有可能成为一个服务器,让别人来访问。

0 请登录后投票
   发表时间:2009-09-11  
我信了阿,为何没有原地复活?
拿到电驴的源码,没有时间看。
以前做过一个p2p的电子杂志下载软件,感觉还可以。
0 请登录后投票
   发表时间:2009-09-11  
在不同的网段之间通讯是比较难的,可以用UDP在路由器上打洞。
如果对效率没有特别要求,可以用webservice,RMI, 或者基于http协议作底层协议,可以穿越防火墙,而且实现起来简单很多。。。
0 请登录后投票
   发表时间:2009-09-11  
dijikstra,应该怀念一下他。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics