分享
 
 
 

JXTAPlatformJAVA参考实现源代码分析(2)

王朝java/jsp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

1 引言

管道的概念源于Unix,是不同线程之间直接传输数据的基本手段。JDK中java.io包中就有管道类,同时,管道在JXTA中是最基本的概念,是对等点之间的数据传输的主要方式。对等管道协议(PBP)明确规范了对等管道的绑定,解析,响应。

本文依次剖析集中式(JDK)和对等环境下(JXTA)管道的实现方式,对比分析其异同,然后尝试在JXTA中建立一个虚拟的全双工的管道。

本文的目标是通过对不同环境下管道的实现方式对比分析,来理解为什么JXTA采用管道作为基本的数据传输手段。

2 管道的形象化描述

一个生活中的情景:现在有两个地区A,B。A是石油生产区,B是石油消费区,现在B地区需要消费A地区的石油,当然可以通过海运,空运获得,然而最通常的方式是架设输油管道。如图所示:

1 引言

管道的概念源于Unix,是不同线程之间直接传输数据的基本手段。JDK中java.io包中就有管道类,同时,管道在JXTA中是最基本的概念,是对等点之间的数据传输的主要方式。对等管道协议(PBP)明确规范了对等管道的绑定,解析,响应。

本文依次剖析集中式(JDK)和对等环境下(JXTA)管道的实现方式,对比分析其异同,然后尝试在JXTA中建立一个虚拟的全双工的管道。

本文的目标是通过对不同环境下管道的实现方式对比分析,来理解为什么JXTA采用管道作为基本的数据传输手段。

2 管道的形象化描述

一个生活中的情景:现在有两个地区A,B。A是石油生产区,B是石油消费区,现在B地区需要消费A地区的石油,当然可以通过海运,空运获得,然而最通常的方式是架设输油管道。如图所示:

java中流的概念和管道的概念都可以通过此案例阐述,A与B之间连接的就是管道,负责将A的石油向B输出。A向管道输出数据(output),B从管道输入数据(input),可以这样理解,管道是A的输出对象,是B的数据源。这里就产生了三个类:输出流A,输入流B,管道。输入流B负责如何获取数据(read 操作),输出流A负责如何消费数据(write操作),管道负责连接它们(connect 操作)。其实,在实现时,管道类分解为管道口,管道出口,由入口出口负责连接。在复杂的网络环境中,这种连接方式可以有专门的网络协议负责(例如,JXTA中的PBP,全称Pipe Bind Protocol)。

由以上描述,我们可以清楚知道最原始的管道就是单向的,文章后面介绍的双向管道,是用两个单向管道虚拟的,而非真实的连接方式。不难发现管道最关键的问题是如何协调输出(A)与输入(B)。这在不同的网络环境会遇到不同的问题,最简单的是同一JVM下的不同过程(线程或任务)之间用同步方式传递数据。而对等环境下,如何去发现对方就是一个很现实的问题,这仅仅只是问题的其中之一,下面的章节会依次分析。

3 集中式环境下管道的实现

问题的描述:A与B是在同一JVM中,A,B有一方能够发现另一方的存在,A将数据发往B方,A发送数据与B接收数据是相互独立的。

现在回到问题的最初:为什么要使用管道?A只管发送,B只管接受,那么数据在哪儿呢?经过下面的分析,就会明白管道把管理数据缓冲区的重任交给了他自己,A,B均是围绕这个缓冲区来启停线程的,显然这才是问题的本质。

JDK中,类PipeInputStream(即前面所述的B)与PipeOutputStream(即前面所述的的A)可以很好的解决这一问题。首先给出类图如下。

下面是将类PipeOutputStream的connect方法代码简化后给予注释。

public synchronized void connect(PipedInputStream snk) throws IOException {

sink = snk; //将PipeInputStream的实例作为PipeOutputStream的一个属性,以便调用

snk.in = -1;//缓冲区的输入位置,<0表示缓冲区为空

snk.out = 0;//缓冲区的输出位置

snk.connected = true;

}

连接以后,PipeOutputStream的write操作直接调用sink.receive(b);这样,对缓冲区buffer的维护,就变成了read()和receive()操作之间的线程同步。JDK对缓冲区的处理非常巧妙,采用了循环列表,它用缓冲区的标志位的变化来代替数据的移动,类似于生活中的时钟把线性的时间规范为24小时来表示。这不属于本文的论述范围,就不继续分析了。

read操作,正常情况下,从out位置读取数据。缓冲区空时进入等待状态。以轮询的方式(1秒间隔)来自我释放。

receive操作,正常情况下,向in位置写入数据。缓冲区满时进入等待状态。同样,以轮询的方式(1秒间隔)来自我释放。

4 JXTA对等管道的实现

通过对JDK的分析,我们可以了解到在集中式环境下,管道的架设方案是比较简单的。在对等环境下(分布式环境下也类似),出于同样的目标,遇到的问题却在急剧的扩大。例如,管道入口和出口之间如何相互发现?数据如何保证在不同的环境下传送?甚至,对管道本身的概念发生质疑:一定是单入口,单出口吗?

JXTA规范中,管道是在端点之上的服务或应用之间发送和接收信息的虚拟连接通道,管道提供在对等端点传输之上的网络抽象。管道有点到点和广播两种通信模式。

JXTA是通过管道广告来唯一标示管道的,输出管道要找到与其广告相同的输入管道才能发送数据,广告内容如下

<!DOCTYPE jxta:PipeAdvertisement

<jxta:PipeAdvertisement xmlns:jxta="http://jxta.org";

<Id

urn:jxta:uuid-59616261646162614A787461503250335003093E73074218AE3ABBE08EF3CBE303

</Id

<Type

JxtaUnicast

</Type

<Name

PipeExample

</Name

</jxta:PipeAdvertisement

如果您需要对JXTA管道有实例化的概念,请参考Sing Li的使p2p能进行交互操作:Jxta命令shell ,这篇文章有部分内容专门介绍了如何在通过shell使用管道。本文主要是从编程的视角去看管道是如何实现的。

4.1 客户视角

Project JXTA : Java Programmer's Guide Chapter7有个例子阐述如何去在对等点之间发送信息,读者可以到www.jxta.org下载源码。现在从客户视角简要的分析它的传送原理,要深入的了解可以看下一节的系统视角分析。

该例中,有两个对等点,并且构建了两个不同的类:一个负责接收(Pipelistener),一个负责发送(PipeExample)。具体的接收次序可以参考时序图:

类Pipelistener实现了接口PipeMsgListener,类PipeExample实现了接口OutputPipeListener。

由时序图(这是两个JVM中的类,所以时序符号是独立标示的)可以清晰的获知,各个对等点的前1,2步是相互独立的。各自的第3步,采用回调的方式建立输入和输出管道。一旦对等系统探测到对方的存在,就分别触发各自的事件发送或接收消息。显然JXTA中管道是异步的。

调试该例程时,注意先建立输入管道,然后建立输出管道。因为,输出管道在一定的时间和次数内探测不到输入管道的存在,就会主动放弃。否则,容易让网络系统在这些无休止的探测中瘫痪。

4.2 系统视角

从上面的例程中,可以了解对等管道的创建方法,以及数据流程,但是不能明确对等系统是如何去实现的。JXTA中管道的实现比在JDK中实现要复杂得多,具体的技术标准可以参考对等管道绑定协议(PBP),此协议规范了JXTA中管道的概念,但并没有涉及到如何去实现,这同样是所有JXTA协议的特征。它们的目标是阐述what it is,而把how to do it留给开发者,这样有利于增强系统的开放性。其中Java参考实现,就是该协议实现的一个案例,以下将具体分析。

首先看管道实现的类图(以单播为例):

关键的类:

InputPipeImpl :输入管道的实现类

NonBlockingOutputPipe :输出管道的实现类

PipeServiceImpl :管道服务的实现类,负责创建输入输出管道

PipeResolver :提供管道绑定的解析服务

通过客户视角的分析,可以得知系统外部是通过PipeServiceImpl来获取输入输出管道。那么消息是如何在对等系统中通过管道过滤和传递的? 从程序实现的角度,涉及到太多的技术细节,JXTA的参考实现中有着庞杂的监听系统。本文尝试用一个案例从两个层次去解析这个问题,两个层次分别是消息的具体形式,服务和端点协议的具体分发策略。很显然,这里我们把注意力放在了管道的架构路径上,而把如何去架构放在了一边,我想它们是有先后关系的,并且距离并不遥远。

5 案例描述

现在假设有两个对等点alas 和sisal ,在一个局域网内,按照客户视角那一节的例程sisal先建立输入管道,alas建立输出管道。由于同一网内可以用广播的方式发送查询信息,可以不设rendevous,并且路由是两点间的,消息传递过程得到了一定的简化。

6 案例分析

以上案例中,从输入输出管道的建立到完成对接并传输数据总共有5个步骤:

sisal建立输入管道

alasl建立输出管道,需要查找输入管道,通过广播向网络发出管道查询消息

sisal获得alas的管道查询消息,通过单播向sisal发出响应表示

alas获得sisal的响应,通过单播向alas发出数据

sisal获得数据

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有