随心所欲

做个幸福的人
posts - 147, comments - 1402, trackbacks - 28, articles - 0
  博客园 :: 首页 :: 新随笔 ::  :: 订阅 订阅 :: 管理

1:基于Socket连接;

2:在四个局域网内测试通过;

3:简单模型,需要进一步优化效率和处理;

 

=========================
备注:
  经过修改和重构,抽象出来的P2PLib已经可以工作了,并且提取出一个Envelope对象,当作通讯协议和数据载体。
  在这个Lib之上,很容易实现不同局域网之间的具体应用,比如现在已经建立了三个应用:
  1:IM,跨局域网即时通讯(UI像MSN)
  2:FT,文件传输,断点续传
  3:DP,数据库代理(客户需要在任何地方访问它局域网内的数据库,这一个其实是作为某ORM的数据层出现的。)


==========================
基本思路

两个分别在不同的局域网内的用户无法直接建立连接并通讯。因为处在不同局域网的用户(没有公共IP)无法被外部机器主动连接,所以凡是所谓的P2P一般都是通过中间服务器中转通讯的。比如在几年前俺曾经介绍过一个P2P的软件,http://www.cnblogs.com/dlwang2002/archive/2005/04/14/207988.html,基本原理那里面有介绍。

这次所建立的模型,是双方都在不同的局域网内部,都没有公用IP

基本原理是这样的。局域网A内用户PA想要和局域网B内的用户PB通讯,那么需要通过中间服务器S进行转接通讯。Socket链接虽然只是由一方发起(局域网内的),但是socket确实一个可以在两端都能通讯的,也就是说,PA链接S后,S实际上可以使用这个通道直接发消息给PA。同理,如果PB连接之后,S将有两个Socket实例,然后S可以把SA的消息直接转发给SB,这样SB就转载了SA的请求到了PB。虽然还是要通过中转,但是S只负责把两端Socket互联,速度延时可近似认为是0,也就是可以认为PAPB是建立了直接的链接,P2P

过程如下:

1:)PAS发出连接请求;S接受请求,并且保留住PAsocket实例SA,存进一个在线用户列表LiveConnections

2:)PB请求S并建立连接(和A无先后关系),S中保存其socket实例SB

3:)PAs发出通讯请求,指明通讯对象是PB

4:)S接收到A的请求,再当前的LiveConnections中找到PBsocket示例SB,转发消息;

5:)PB接受到来自PA的消息。

 

 

主要程序代码

   1:)首先的问题是如何建立Socket连接。这个问题在以前的一篇Blog中有提到(http://www.cnblogs.com/dlwang2002/archive/2008/07/21/924803.html)。这里使用的代码基本上都是和那一个一样的,只有中间处理通讯数据的部分稍有不同。这些代码不再赘述。

   2:)服务器S处理转发消息的代码

                 

Code


   3:)客户端的简单实现

 

ConnectionManager

    
  4:)UI等其他处理 (略)

 

问题

1:)一个Socket的实例可以在服务器/客户端存活多久呢?我测试发现,至少几个小时没有问题,但是最长时间却不知道。

    2:)服务器S用单独的线程来处理链接,并不是最好的方式

    3:)服务器负载平衡,在多个服务器的情况下,要让客户端可以选择效率最高的服务器进行中转

    4:)有一台机器已经在公网上,或者两台都在公网上,需要另外的模型。他们不需要中转。

 

小结

    简单,效率未知。
server.jpg
client.jpg

Feedback

#1楼    回复  引用  查看    

2008-09-16 17:13 by kkun      
问题1我也很想知道

#2楼    回复  引用    

2008-09-16 17:17 by KEN-张 [未注册用户]
我认为这也不能叫做P2P
服务器应该只起到一个用户列表和辅助两个终端建立连接的作用,而不参与转发
S 收集到A和B的相关信息,告诉分别通知双方,双方再自己去完成后面的事

#3楼    回复  引用  查看    

2008-09-16 17:36 by 飘遥      
服务器是媒人,
媒人将两人介绍成功后过日子的是两口子,
当然期间有大的矛盾需要媒人帮忙解决~

#4楼 [楼主]   回复  引用  查看    

2008-09-16 18:35 by 随心所欲      
@kkun
三个小时还没有断(到现在为止),基本上可以认为是长期的了。
只是不知道具体多长时间。

#5楼 [楼主]   回复  引用  查看    

2008-09-16 18:41 by 随心所欲      
@飘遥
不知道你有没有注意到,在我贴出的服务器的图上,每一次链接其实终端(EndPoint)都是不一样的:
xxx.xxx.xxx.xxx:50552;
xxx.xxx.xxx.xxx:50553;
xxx.xxx.xxx.xxx:50554;
....
也就是说,就算是同一台机器,在不同的socket连接上,终端地址是不一样的。
PA连向S的时候分配了一个50552,如果你想把这个地址直接给PB使用,让他链接这个50552,这个似乎是不可能的,因为当你再连过来,新的socket可能已经是50553了(没有测试过,似乎看过一篇文章如是说)。
所以,还是需要服务器中转一下的。

如果能有不中转的方法,当然效率要更高一些。

#6楼    回复  引用  查看    

2008-09-16 21:05 by 亚历山大同志      
看看sip协议先

#7楼    回复  引用  查看    

2008-09-16 21:47 by 包建强      
好文啊好文,这门技术我找了很久!

#8楼    回复  引用  查看    

2008-09-16 23:49 by 5207      
这样估计客户端在连接公网服务器S的时候会有问题。不知道是否测试过?

#9楼 [楼主]   回复  引用  查看    

2008-09-17 09:45 by 随心所欲      
@亚历山大同志
如果您知道答案,请不吝赐教。

#10楼 [楼主]   回复  引用  查看    

2008-09-17 09:47 by 随心所欲      
@包建强
已经加上。顺便把的联系方式删掉了(可能会引起不便)

#11楼 [楼主]   回复  引用  查看    

2008-09-17 09:48 by 随心所欲      
@5207
测试过,没问题。
在四个不同局域网内的用户可以通过一个S进行点对点通讯

#12楼 [楼主]   回复  引用  查看    

2008-09-17 09:53 by 随心所欲      
@kkun
到现在为止,socket链接已经近20个小时。还没有问题。服务器运转正常。

#13楼    回复  引用  查看    

2008-09-17 11:39 by NoText      
学习了,谢谢lz分享

#14楼    回复  引用  查看    

2008-09-17 14:03 by 亚历山大同志      
LZ,此文只能叫实现防火墙穿透的例子啦,要实现P2P还有很多要做的工作

#15楼 [楼主]   回复  引用  查看    

2008-09-17 14:39 by 随心所欲      
@亚历山大同志
还有哪些,请一一指出。
我觉得实现了这些基础,剩下的只是根据具体需求做实现了。

#16楼    回复  引用    

2008-09-17 15:33 by 成功人事 [未注册用户]
学习一下,感觉是个不错的开始.

#17楼    回复  引用  查看    

2008-09-17 17:47 by 清凉一夏      
关注中......

#18楼 [楼主]   回复  引用  查看    

2008-09-18 09:36 by 随心所欲      
经过修改和重构,提取出一个Envelope对象,当作通讯协议和数据载体。
修改之后的P2PLib已经可以工作了。
在这个Lib之上,很容易实现不同局域网之间的具体应用,比如现在已经建立了三个应用:
1:IM,即时通讯
2:FT,文件传输
3:DP,数据库代理(客户需要在任何地方访问它局域网内的数据库,这一个其实是作为某ORM的数据层出现的。)

#19楼    回复  引用  查看    

2008-09-24 22:18 by BAsil      
收藏,慢慢学习

#20楼    回复  引用    

2008-10-11 01:30 by myw_fool [未注册用户]
服务器的任务是打洞,而不应该参与转发数据

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-09-18 09:41 编辑过
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》



相关文章:

相关链接: