P2P应用正日趋成熟,本文就介绍一种基于JXTA框架的P2P应用开发方法。
网络技术的飞速发展与迅速普及使其成为数据通信的重要手段,网络规模越来越大,连入网络中的计算设备的数量和种类也越来越多,而这些资源并没有得到充分利用,如果能将这些计算单元的处理器计算能力、磁盘存储能力、网络带宽资源等进行充分利用将会有效缓解目前互联网所面临的一些问题。
P2P(Peer to Peer,对等网络)就是在这种背景下提出的一种网络技术。它是一种与传统的C/S或多层服务器网络完全不同的网络体系结构,P2P网络中的对等点是彼此直接通信的。与目前互连网上比较流行的C/S 计算模型不同的是:P2P 计算模型中不再区别服务器以及客户端,系统中的各个节点是逻辑对等的,系统中的各个节点之间可以直接进行数据通信而不需要通过中间的服务器,可以认为它的任何一端同时具有Client和Server 的功能。一些P2P应用也许在某些时候使用服务器,但P2P计算的总体影响是将网络计算分散,它使真正的分布式计算成为可能。
本文将在上述背景下讲述如何使用著名的JXTA框架来进行日趋流行和成熟的P2P应用程序的开发。
JXTA框架简介
JXTA最早起源于2000年的夏天,该技术的目的是为P2P的网络应用开发提供一个统一的、开放的平台,现在大家把JXTA看成是P2P的平台,JXTA的目标是要解决几个技术与商业上的难题。
● 第一是解决众多P2P系统互不相通的问题。
● JXTA的另外一个目的就是找寻一套数量最少、概念最简单的系统构成的“积木”。如果成功,这几块积木就会是今后大家构架信息系统的基本模块,从而帮助人们摆脱像Windows或TCP/IP这样的传统软件带来的包袱。
JXTA技术提供了基础性的机制解决当前分布计算应用中面临的问题,实现新一代统一、安全、互操作以及异构的应用。目前它支持基于Java技术的平台和系统。而将来JXTA技术将不受到内存的限制而支持更多小型移动设备。JXTA通过Java技术和XML数据表达的结合,提供了强大的功能使得垂直应用得以交互,并且可以克服目前P2P软件中的限制。同时,通过小型、简单、便于开发的构造模块,JXTA将使开发者从建立各自框架的复杂工作得以解放,可以潜心关注于建设各类新颖、创造性的、分布式计算应用。
P2P网络的一个非常重要的特点就是各个对等点之间可以直接通信,至少是可以访问到的。而在现实的网络中,由于防火墙、NAT、和动态IP等原因,有许多计算机是不能相互访问的,在JXTA网络中就必须解决这个问题。P2P网络不是推翻现有的网络结构,而是在现有的网络上构建一个符合P2P特点的网络,如图1所示。
图中中间虚线下面是现有的物理网络拓扑结构,网络中有许多计算机通过现有的TCP/IP协议或者是HTTP协议进行通信;而虚线上面是一个虚拟的JXTA P2P网络,通过把虚线下面现有的网络映射成为P2P网络。另外,既然是在现有网络上构建一个P2P网络,就必需考虑到现有网络上存在的多平台、多语言的情况。
在充分考虑现有P2P系统功能的前提下,为了克服现有P2P系统的缺陷,JXTA项目的 P2P网络的目标应该包括以下几个方面:
● 互操作性:P2P系统应该能够使内部连接很容易地找到彼此,彼此间进行交流,加入基于团体的活动,提供无缝跨越不同P2P系统和不同团体的服务。
● 平台无关性:P2P系统应该设计成独立于编程语言,如C、JAVA等,独立于系统平台,如Windows和Unix,独立于网络平台如TCP/IP和BLUETOOTH。
● 广泛性:P2P系统应该设计成可以在任何有数字处理功能的设备上使用,包含传感器、消费电子设备、个人数字助理、网络路由器、桌面计算机、中心服务器和存储系统。
JXTA项目层次结构
JXTA由三层组成,如图2所示。第一层是JXTA核心层,它包含了服务所需要的核心功能;第二层是服务层,它提供了访问JXTA协议的接口;第三层是应用层,它使用服务来访问JXTA网络和JXTA提供的功能。这样的设计和一个标准的操作系统比较相似,标准的操作系统包括核心操作系统、服务和应用程序。
各层的说明如下所示:核心层(JXTA Core)提供了对P2P应用与服务的核心支持。其中,对等组建立一组对等点并在组中分别命名,并且对创建、删除、成员管理、公布以及搜索其他对等组和对等点、通信、安全、内容共享等基本功能都设定了相应机制;管道在对等点之间提供通信,在管道中传输的信息通过XML格式化,并且在某种意义上是不依赖特定协议的;对等点实体监视器用来控制一个对等组中某个对等点的行为;安全提供基本的平台级安全保障。
另外,服务层(JXTA Services)包括对于P2P网络不是必需的,但很通用的功能,如查找、共享、索引、代码缓存和内容缓存的机制。应用层(JXTA Application)包括了应用JXTA服务开发出来的完整的P2P应用程序,为用户提供最终的界面和整体解决方案。
JXTA协议族
有六个协议构成了JXTA的核心,JXTA通过这六个协议来完成对等点之间的通信,彼此之间的资源的发布和发现,信息的传递和路由,协议本身并不是应用程序,需要添加更多的代码来开发有用的应用,协议隐藏了很多细节,这样使得编写JXTA应用程序比从空白开发P2P应用要容易得多。
JXTA项目在JXTA协议规范中定义了它的协议。此规范描述了对等点间如何通信和交互,它并未描述实现的细节或如何编写P2P应用程序。Sun已为JXTA 提供了初步的 Java 语言实现。从编写P2P应用程序的角度而言,可以简单地划分上述协议的主要用途:表1简要描述了JXTA协议的核心集。这些协议都是建立在 XML 消息交换的基础上的。JXTA规范不要求对等点实现上述所有协议。任一个特定的对等点只需实现那些实际要用到的协议。
应用程序开发实例
目前JXTA项目框架只有JAVA的实现版本,这里就通过一个简单的JXTA应用实例,描述一下应用JXTA开发P2P程序的过程及其运行配置。
程序的设计与实现
本程序构造了两个对等点实体,一个用于提供服务,我们给它起名为服务实体,服务实体建立一个输入管道,并且广告此管道,通过监听输入管道,服务实体等待从客户方到来的消息。另外,我们建立一个用于发现服务实体并且通过与服务实体建立的管道向服务实体传递消息的实体,我们把这个实体称之为用户实体,用户实体通过服务实体广告的内容找到服务实体提供的管道,并通过SendMessage()方法向管道发消息。
(1)服务实体的处理:
//服务实体通过startApp()启动服务。
Public int startApp(String[] arguments)
{
//首先通过广告机制建立一个管道广告
PipeAdvertisement pipeAdvertisement=( PipeAdvertisement)AdvertusementFactory.newAdvertisement(PipeAdvertisement,getAdvertisementType());
//设置管道广告的标志号为本对等实体组的标志号。
PipeAdvertisement.setPipeID(newPipeID(this.peerGroup.setID()));
//设置管道广告的名字,以便其他的对等实体通过该名字访问此管道。
PipeAdvertisement.setName(“SimpleService:”+this.peerGroup.getPeerID());
//通过发现机制的发布方法,发布建立的管道广告,同时远程发布此管道广告。这样其他的对等实体就可以查询访问这些管道了。
This.discovery.localpublish(pipeAdvertisement,Discovery.ADV);
This.discovery.remotePublish(pipeAdvertisement,Discovery.ADV);
//建立输入管道,通过此输入管道,服务实体就可以与用户实体实现通信。
This.helloPipe=this.pipes.createInputPipe(pipeAdvertisement);
}
启动服务之后,服务实体就可以建立一个线程,在此线程中循环等待直到有消息到来。
(2)客户实体的处理
public void sendMessage(){
//首先通过PDP发现机制中的getRemoteAdvertisements()方法查询名为SimpleService的服务管道名,此查询消息通过路由实体进行传播。查询回应的信息传回后存放到客户实体的本地机器中。
This.discovery.getRemoteAdvertisements(null,Discovery.ADV,”name”,”SimpleService:”,10);
try{Thread.sleep(10000);}
catch(InterruptedExceptionerror){}
//等待一段时间之后,客户实体通过getLocalAdvertisements()查询本地机器,找到服务实体发布的管道广告。
try{Enumeration pipeEnumeration=this.discovery.getLocalAdvertisements(Discovery.ADV,”name”,”SimpleService:”);
while(pipeEnumeration.hasMoreElements())){Advertisement
advertisement=(Advertisement)pipeEnumeration.nextElement();
//建立以所发现的管道广告为参数的输出管道,这样就可以通过此输出管道与服务实体的输入管道进行连接了。
OutputPipe outputpipe=this.pipes.createOutputPipe(pipeAdvertisement,Pipe.NonBlocking,-1);
//建立要发送的消息,通过输出管道发送消息。
MessageoutMessage=this.pipes.createMessage();
outMessage.push(sendername,newByteArrayInputStream(this.peerGroup.getPeerID.toString().getBytes()));
outputPipe.send(outMessage);
}
JXTA平台的运行配置
JXTA程序开发完后,第一次运行时,JXTA的自动配置工具就会显示出来,用于配置JXTA平台的网络环境,包括对等点的信息、TCP/IP和HTTP的配置、Rendezvous和Relay Peer,以及安全信息。
在程序启动时,JXTA会在当前目录下寻找PlatformConfig文件,找到之后就从中加载配置信息;否则,配置界面要求用户输入对等点的配置信息,配置完毕后,当前目录下会出现PlatformConfig文件、cm目录(用来在本地缓存JXTA广告信息)和pse目录(用于保存用户名和密码信息)。
JXTA标志符(Identifiers)
标志符用于指明资源而非物理网络地址,必须保持其在JXTA网络中的惟一性和持久性。JXTA定义了许多标志符。它们可用于验证、索引和检索。在大多数的广告中都有两个特殊的标志符,一个是广告的ID,另一个是广告的类型。广告一经产生,ID也就生成。我们可以将广告的标志符看做一个对象的引用(Reference),它旨在赋予每一个广告一个惟一标志。
标志的形式随它们的意图和应用的不同而不同。它们既可以是简单的名字,又可以是由相当的数字和字母组成的独一无二的标志。在JXTA中的一些主要标志符如下:
● Codat ID:Codat定义为JXTA组内共享和交换的信息单元。而Codat ID指向Codat。对等组缓存服务提供了以Codat ID为索引保存和引用Codat的方法。
● Peer ID:用于引用对等节点,它的生命期同对等点一样长。
● Group ID:用于对等组的引用,用于确定与检索对等组。
● Service/Module ID:用于定义Codat。每个ID都只与惟一的代码相关联。
● Pipe ID:管道ID用来标明一个组内或一种服务的通信管道。
链接: JXTA网络核心概念
Peer(对等点)
Peer是一个虚拟的通信点。在一台计算机或者设备上可以有很多个对等点,一个对等点并不是一个用户,因为一个用户可以有多个对等点,同一个设备上也可以有多个对等点(在测试的时候经常用到)。对等点与特定的网络服务联系得很紧,在JXTA的参考实现中,对等点可以使用网络提供的基本服务,这些基本服务又可以提供搜索和通信服务,一般来说,并不是所有的对等点都使用这些服务,它们只使用这些服务的一部分。
PeerGroup(对等组)
对等组是可以通过对等组协议进行交互的一个虚拟实体,它是一种组织对等点(Peer)并且发布组内的特定服务的方式。对等组可以被创建、加入和退出,在一个组里还可以更新一个组成员的关系,由于一些原因,对等组需要对成员关系进行一些限制,例如为了通信的安全、隐私的考虑等。这里使用一种协议来认证,它专门收集信息并判断其是否符合成员关系的要求。总之,对等组是一个为提供通用服务而相互协同工作的一组对等点的集合。
对等网络计算(P2P)最终将使整个可连接设备组成一个巨大的虚拟对等计算系统网络。然而,在实际的环境中,由于多方面的原因,将网络分隔成许多不同的部分可能是非常有意义的。JXTA以对等组(PeerGroup)的形式提供了此类网络分隔。
服务
JXTA的服务主要提供给对等组内的成员共享。事实上,一个对等点加入到对等组的主要目的就是为了得到组内的服务。一组高效的核心服务对于实现JXTA网络的基本操作是致关重要的。表2列出了在JXTA1.0中所规范的核心服务。
Pipe(管道)
管道是对等点之间的虚拟通道,是用来在对等点之间接收和发送异步消息的通信管道。
逻辑上,JXTA的通信管道属于对等组内的资源,它是通过通信管道服务来实施的。通常,我们认为对等通信是单个的通信连接,但是也并不总是这样的,因为防火墙和其他障碍的存在,许多对等点并不能直接连接,这时,管道更像一个在多种通信协议之上的虚拟层,可以通过起网关作用的对等点对通信提供中继支持。
管道是JXTA最基本、最重要的特性,它提供了一种很好的方案,使得对等点在大多数网络情况下都可以通信,而不用去管防火墙或者其他的障碍,即使不知道另外一个对等点的位置以及它所使用的协议等信息,通过管道仍然可以与之通信;管道作为一种抽象的方法,隐藏了一些细节,比如在多个连接的时候可能会有多个对等点参与进去,管道也可以重新定位,找到原来的对等点。
Message(消息)
JXTA网络中的所有通信都是通过发送和接收消息实现的。JXTA消息是从一个对等节点通过管道传输到另一个对等节点的数据包,这些消息由封装袋和主体组成,用XML文档编码,是实现交互操作性的关键(另一个为协议)。封装袋具有标准的格式,主体可以携带任意长度、任何内容的数据。用任何编程语言实现的对等节点可以从一个JXTA管道里读消息或广告数据,产生输出,将结果写到另一个JXTA管道中。
Advertisement(广告)
一个广告就是一个XML文档,它用来描述JXTA的消息、对等点、对等组或者服务等。广告都遵守编码、标签和内容的标准,广告用来交换JXTA网络上可以获得的任何信息。例如,一个对等点创建了名称为“team_A8”的对等组后,就可以使用IP多播方式把广告发布到本地的JXTA网络;也就说,子网中的每一个对等点都会收到一份广告的副本,此外广告还会被发送到集合点去。