分享
 
 
 

JXTA探索:双向管道(Bi-directional Pipe)的实现和原理剖析

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

jxta[/url]探索:双向管道(Bi-directional Pipe)的实现和原理剖析

* 什么是管道(Pipe)?

管道是[url=http://www.jxta.org]jxta[/url]里面比较重要的一个概念。管道是Peer之间的虚拟通道。通常,我们认为对等通信是单个的通信连接。但是也并不是总是这样的。因为防火墙、NAT和其它障碍的存在,许多Peer并不能直接连接。这时,管道更像一个在多种通信协议之上的虚拟层,可以通过起网关作用的Peer对通信提供中继支持。

使用它的好处在于,不用去关心Peer所使用的真正的地址和协议是什么,使用抽象出来的管道,可以为P2P应用提供强大的功能并降低复杂性。

* 为什么要分析双向管道的实现原理?

在JXTA的J2SE参考实现中,提供了三种最基本类型的管道,它们分别是:

a 单向管道(UnicastType)

b 单向安全管道(UnicastSecureType)

c 广播管道(PropagateType)

而实际应用中,可以通过基本类型的管道的组合形成一些更有用的类型,如双向管道(Bi-directional Pipe)。因为我们知道在P2P应用中,如聊天,传送文件等操作都需要实现双向管道。在JXTA的J2SE参考实现中提供了两个有用的类(JxtaBidiPipe和JxtaServerPipe),通过一种巧妙的机制,实现了一个双向管道。

尽管在使用双向管道时,不需要了解内部的实现方法,但是我认为理解双向管道的实现机理对于使用双向管道有一定的帮助,对于进一步分析[url=http://www.jxta.org]jxta也是有益的,希望通过下面的分析,能给jxta应用的开发者一些有益的提示,同时也作为本人的一个参考。

因为jxta在推出后一直在不断的发展中,2.0和1.0版本之间出现了很多的不一致,因此声明,本文列出的代码均基于最新的JXTA2.0 API,在Jxta的J2SE参考实现2.3.1版本上调试通过。

* 用JXTA建立双向管道的过程

编写一个双向管道的应用程序需要用到如下两个类:JxtaBidiPipe和JxtaServerPipe,它们共同实现了一个握手协议,即 使用一个由连接双方共同填写的结构化xml文档,在jxta[/url]里用Message来描述这个文档, 该Message有以下内容

<Credential>决定请求者是否有获得连接的权利<Credential>

<reqPipe>请求者的管道广告(pipe advertisement)</reqPipe>

<remPipe>远程的管道广告(remote pipe advertisement)</remPipe>

<remPeer> 远程的节点广告(remote peer advertisement)</remPeer>

<reliable> 是否可靠性连接 ("true", or "false") </reliable>

<data> 通讯数据 <data>

而实际建立和使用双向管道的过程中,并不需要了解这个Message的,这里只是为后面分析建立的原理作准备。

我们知道,即使是在P2P系统中,也有一个连接发起节点(这里设定为PeerA),和一个连接接受节点 (这里假定为PeerB)

首先在发起节点A在程序当中使用如下语句发起JxtaBidiPipe连接:

try {

FileInputStream is = new FileInputStream("pipe.adv");

eg.pipeAdv =

(PipeAdvertisement)AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8, is);

is.close();

System.out.println("creating the BiDi pipe");

eg.pipe = new JxtaBiDiPipe();

eg.pipe.connect(eg.netPeerGroup,

null,

eg.pipeAdv,

180000,

// register as a message listener

eg);

} catch (Exception e) {

System.out.println("failed to read/parse pipe advertisement");

e.printStackTrace();

System.exit(-1);

}

在节点B处用如下方法响应这个连接:(这里用到了JxtaServerPipe,这是一个辅助类,它的行为非常类似JDK开发中常用的类ServerSocket)

try {

FileInputStream is = new FileInputStream("pipe.adv");

eg.pipeAdv =

(PipeAdvertisement) AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8, is);

is.close();

eg.serverPipe = new JxtaServerPipe(eg.netPeerGroup, eg.pipeAdv);

// we want to block until a connection is established

eg.serverPipe.setPipeTimeout(0);

JxtaBiDiPipe bipipe = serverPipe.accept();

if (bipipe != null ) {

System.out.println("BiDi Pipe created");

receiveAndSendTestMessage(bipipe);

}

} catch (Exception e) {

System.out.println("failed to read/parse pipe advertisement");

e.printStackTrace();

System.exit(-1);

}

建立了双向管道的连接后,就可以进行简单的通讯了。

注意到,这里JxtaBidiPipe和JxtaServerPipe的行为非常类似JDK里面的Socket和ServerSocket。我想这是JXTA[url=http://www.jxta.org]的设计者有意为之,目的是使得Java开发者更方便的使用这些类。

* jxta[/url]双向连接对象(JxtaBidiPipe类型对象)的使用

可以用isBound()来判断出JxtaBidiPipe对象的双向连接是否建立。

可以用getMessage()来接收JxtaBidiPipe上的消息。

可以用sendMessage()在JxtaBidiPipe上发送消息。

* 双向管道建立的原理的源代码剖析

在分析之前,现分析一下[url=http://www.jxta.org]jxta[/url]里面一个单向管道的大致建立过程,因为双向管道实际上就是两个双向管道的组合。

单向管道的建立过程比较简单(以两个节点PeerA和PeerB为例)

(1)首先PeerA根据一个管道的广告建立一个输入管道(Input Pipe) 等待连接;

(2)PeerB根据同样的广告建立一个输出管道(Output Pipe);

(3)如果PeerB的输出管道建立成功,则PeerB会收到相应的连接已经建立的提示(通过响应outputPipeEvent),这时一个从B到A的单向连接就建立起来了,在A中可以通过响应pipeMsgEvent来得到B发送过来的消息的提示,并得到消息的内容。

这样实现的一个单向管道除了只能单向传输外,还有一个显著的缺点在于它要求通信双方必须使用一个共同的管道广告(广告一般用一个组内发布的xml文档来表示),而且在双方发送消息的时候,该文档定义的管道广告一直被使用,不能再用来建立新的连接。

如果按照一般的思路,建立双向管道就需要使用两个共用的管道广告,并在双向通信过程中一直占用这两个管道广告。

而实际上,JXTA里面实现的双向管道,只在初始时使用了一个共用的管道广告PublicPipeA2B advertisement(可以考虑使用组内的服务实现),而后通过巧妙的机制,建立了两个内部使用的管道广告(即不用发布, 分别为privatePipeB2A和privatePipeA2B的advertisement),并用这两个内部管道广告实现了双向通信,并且通信建立以后,原先的共用的管道广告对于该通信过程就无用了,还可以被别的通信管道再次利用。

下面按照时间顺序,分析一个双向管道的建立过程:(序号后面的字母表明是在哪个节点进行,如”1B”表示该动作发生在Peer B)

(1B)节点B处新建一个JxtaServerPipe对象,JxtaServerPipe本身是一个InputPipe, 在它构造的时候使用共用的广告,即publicPipeA2B的advertisement建立一个输入管道等待连接。

(2A) 节点A新建立一个输入管道Inputpipe(就是privatePipeB2A), 并将这个管道的广告,即privatePipeB2A的advertisement封装到一个消息Message里, 这个Message的消息一共填写了Credential, reqPipe, remPeer, reliable四个部分,我们这里只关注reqPipe部分,这里存放的就是广告privatePipeB2A advertisement(参照JxtaBidiPipe的createOpenMessage方法)

(3A) 节点A用publicPipeA2B的advertisement来建立输出管道OutputPipe ,这样就与节点B建立了一个AàB的单向连接。 连接建立以后, 马上把第(2A)步产生的Message用这个管道publicPipeA2B发送给B, 然后又进入等待。(参照JxtaBidiPipe的connect方法)

(4B) 节点B用上面第(2a)步里面接受的Message里包含的reqPipe部分的pipe advertisement建立一个OutputPipe(就是PrivatePipeB2A), 这时就会连接到上面在第(2A)步建立的PrivatePipeB2A的InputPipe上, 到这一步就建立了一个B到A的内部连接管道privatePipeB2A。(参照JxtaServerPipe的processMessage方法)

(5B) 节点B新建立一个InputPipe(就是privatePipeA2B的输入管道), 并把Message的remPeer部分填写上这个新建立的管道的广告,即privatePipeA2B的advertisement,(实际上填写了Credential, remPipe, remPeer三个部分,我们这里只关注remPeer部分),用第(4B)步建立的连接管道PrivatePipeB2A把这个填写好的Message发回给节点A。(参照JxtaServerPipe的processMessage和sendResponseMessage方法)

(6A) 节点A处接收到这个消息后马上用这个remPeer部分包含的privatePipeA2B 的advertisement建立一个输出管道OutputPipe。到这一步就建立了一个新的A到B的连接管道privatePipeA2B,而先前建立的A到B的管道publicPipeA2B就可以不用继续使用了,然后结束第(3A)步的等待,这时一个包含privatePipeA2B和privatePipeB2A的双向管道,即一个JxtaBidiPipe对象就正式建立(绑定)成功了。

*结束语

还有一对JXTA的类JxtaSocket和JxtaServerSocket,实现的机理和上面的方法大致类似,根据JXTA开发者的说法,JxtaBidiPipe和JxtaServerPipe适用于小数据量应用,如即时消息,聊天信息等;而JxtaSocket和JxtaServerSocket适用于大数据量的通信,如文件传输等。我将在下一篇里分析JxtaSocket和JxtaServerSocket的例子。

本文用到的程序请参照[url=http://www.jxta.org/ProgGuideExamples.zip]http://www.jxta.org/ProgGuideExamples.zip

里面的JxtaBidiPipe一节,

还可以到这里下载JXTA的J2SE参考实现2.3.1版本的源代码:

http://download.jxta.org/build/release/2.3.1/jxta-src-2.3.1.zip

( 感谢曾经在JXTA上的同行的探讨和总结对我的启发,转载请注明出处)

yanqlv

2004/10/23

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有