* 什么是管道(Pipe)?
管道是
jxta里面比较重要的一个概念。管道是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上发送消息。
* 双向管道建立的原理的源代码剖析
在分析之前,现分析一下
jxta里面一个单向管道的大致建立过程,因为双向管道实际上就是两个双向管道的组合。
单向管道的建立过程比较简单(以两个节点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
分享到:
相关推荐
总之,《End-to-end Sequence Labeling via Bi-directional LSTM-CNNs-CRF》的代码实现是一个综合运用深度学习技术解决自然语言处理问题的实例,通过NeuroNLP2库,研究者和开发者可以更方便地复现和改进这一模型,...
然而,随着技术的发展,双向充电能力的需求正在增长,即Bi-Directional-Capable OBC,这允许车辆不仅从电网充电,还能向电网馈电(V2G)或对其他设备供电(V2H、V2L)。设计这种双向OBC时,工程师需要考虑一系列关键...
4-Switch Buck-Boost Bi-directional DC-DC Converter buck-boostDC-DC buck-boostDC-DCDC-DC buck-boostDC-DC buck-boostPMP21529 buck-boost buck-boost buck-boost buck-boost buck-boost buck-boostDC-DC ...
标题中的“Bi-Directional DC-DC Converters for Plug-in.rar_DAB_DC_DC/DC_con”暗示了我们讨论的主题是双向直流-直流(DC-DC)转换器,特别是在插电式应用中的应用。这种转换器在电力电子学中扮演着重要角色,用于将...
### 双向注意力流模型(Bi-directional Attention Flow, BAF)在机器阅读理解中的应用 #### 模型概述 **双向注意力流模型**(Bi-directional Attention Flow, BAF)是一种专门针对机器阅读理解任务设计的有效方法...
State-of-the-art sequence labeling systems traditionally require large mounts of task-specific knowledge in the form of hand-crafted features and data pre-processing.In this paper, we introduce a ...
为了解决这个问题,研究人员提出了“Rumor Detection on Social Media with Bi-Directional Graph”这一创新方法,它利用双向图神经网络(Bi-Directional Graph Neural Networks,简称Bi-GNN)来识别和抑制虚假信息...
SAE Functional Safety Development of Bi-Directional On-Board Charger for New Energy Vehicles
Rumor Detection on Social Media with Bi-Directional Graph 论文
"voltage_source_converter.rar_Voltage matlab_bi-directional_contr"是一个关于双向电压源转换器的MATLAB模型,其中包含了控制器设计,特别是dq坐标系下的控制策略。 双向电压源转换器(Bi-directional Voltage ...
其基本工作原理是利用N-MOS管作为开关,通过控制栅极电压来调节源极和漏极之间的导通状态,从而实现信号从一个电压域到另一个电压域的传输。 **电路组成** 一个简单的双向电平转换器由两个N-MOS管构成:一个用于上...
"Privacy-Enhanced Bi-Directional Communication in the Smart Grid using Trusted Computing"这个主题探讨了如何通过可信计算技术来解决这些隐私问题。 首先,智能电网的双向通信涉及到大量的敏感信息,包括用户...
这意味着,通过同时利用Bi-LSTM架构和修改后的三元组损失函数,所提出的模型可以在现实复杂场景中实现更准确的人像匹配。 四、总结 本文提出的Bi-LSTM结合修改后的三元组嵌入,是人像再识别领域的一个重要进展。它...
Bi-Directional Replication (BDR) 是 PostgreSQL 的异步多主复制系统,专门为允许地理上分布的集群而设计;支持最多 48 节点(未来版本还可能更多;是一个低开销,低维护技术,分布式数据库。
Dual Active Bridge articles
- **储能系统**:在储能应用中,REF-DAB11KIZSICSYS板能够帮助实现能源的有效管理和分配。 - **可再生能源发电系统**:对于太阳能或风能发电系统而言,该板可以作为逆变器或转换器的核心部件。 #### 6. 安全注意...