基于 C++ JXTA 开发出一个组内聊天和共享文件的软件

♻️ 资源

大小: 62.5MB

➡️ 资源下载: https://download.csdn.net/download/s1t16/87450294

利用 JXTA 开发出一个组内聊天和共享文件的软件

摘要

Peer-to-Peer 网络毫无疑问是当今的热点技术主题。Napster 和 Gnutella 的广泛使用证明了 peer-to-peer 应用的强大潜力。P2P(或者说 peer-to-peer)网络是一种基于操作上下文的网络模型,任何一个节点都同时作为客户机和服务器。JXTA 致力于为 P2P 应用提供一个 P2P 平台基础。其中包括一系列独立于语言,平台和网络技术之外的协议。这些协议解决了 P2P 应用的基本需求。协议的设计目标是简单并且低成本。本论文设计探讨了 P2P 网络的结构和 JXTA 的基本知识,并利用 JXTA 开发出一个组内聊天和共享文件的软件。

关键词: P2P,Peer,PeerGroup,Advertisment,XML,JXTA,CMS

ABSTRACT

Peer-to-Peer (P2P) network is a hot topic in technology in recent years. The wide use of Napster and Gnutella demonstrated the powerful potential in application of P2P. The P2P network is a model of network which based on the environment of operation, and each node can work as client and serve at the same time. JXTA offers a basic platform for the application of P2P. And it includes a series of treaties which independence from languages, platform and technique of network. These treaties can meet the basic requirement of the application of P2P。The aim of these treaties is compact and the cost must be low. This article has discussed the structure of P2P network and the basic knowledge of JXTA, and developed a software for chat and share documents in a group from JXTA technique.

Key words: P2P,Peer,PeerGroup,Advertisment,XML,JXTA,CMS

绪论

最近,P2P(Peer-to-Peer)又成为了因特网上的一个热点。P2P 是因特网的一种应用模式,其意思是指网络上的任何设备(包括大型机、PC 机、PDA、手机、机顶盒等等)都可以平等地直接进行连接并进行协作。相比当前因特网上主流的应用模式 Client/Server 或者 Client/Service 而言,P2P 具有自己鲜明的特点和优势。

是 peer-to-peer 的缩写,peer 在英语里有"(地位、能力等)同等者"、"同事"和"伙伴"等意义。这样一来,P2P 也就可以理解为"伙伴对伙伴"的意思,或称为对等联网。目前人们认为其在加强网络上人的交流、文件交换、分布计算等方面大有前途。

简单的说,P2P 直接将人们联系起来,让人们通过互联网直接交互。P2P 使得网络上的沟通变得容易、更直接共享和交互,真正地消除中间商。P2P 就是人可以直接连接到其他用户的计算机、交换文件,而不是像过去那样连接到服务器去浏览与下载。P2P 另一个重要特点是改变互联网现在的以大网站为中心的状态、实现"非中心化",并把权力交还给用户。

发展简史

并不是一个新的概念,早在 1969 年因特网的前身 ARPANET 刚出现的时候,网络的应用模式就是 P2P,ARPANET 的最初目的是在全美国范围内共享计算机资源,其所面临的挑战是如何集成当时各种不同的网络,使之成为一个通用的网络,并且使得各个主机成为网络上平等的成员。ARPANET 是以一种平等的计算 Peer 的方式把这些计算机系统连接起来,而不是用 Master/Slave 或者是 Client/Server 的方式连接。

早期的因特网比现在的因特网更加开放和自由,例如在 20 世纪 80 年代之前,人们从未听说过防火墙的概念。就通常意义而言,当时的网络上任意两台计算机都可以给对方发送网络包,网络就是人们进行协同研究工作的场所,不需要提防任何东西。后来因特网上出现了 FTP 和 Telnet 这样的比较受欢迎的应用程序。虽然它们单个的应用程序都是 Client/Server 方式的,但是整体上的使用模式却是对称的。网络上的每台主机都可以 FTP 或者 Telnet 到其他主机上,同时自己也可充当服务器。

DNS 是另一个仍在使用的 P2P 的经典例子,DNS 的作用就是把因特网的域名和 IP 地址进行映射,最早的时候这个映射是保存在一个大文件中的,并在因特网上进行复制。随着因特网规模的增大,必须采用一种方式来进行域名数据的共享。DNS 提供了一种实现文件共享的解决方案,采用了层次性的信息归属办法,即我们通常所说的域名层次。DNS 之间可以相互交换域名信息,这个时候,每个 DNS 也可能是服务器(接收其他 DNS 的请求),也可以是客户端(向其他 DNS 发出请求)。

从 1995 年开始,随着 PC 机的广泛使用并接入因特网,成千上万的人挤到因特网上,他们使用因特网的方式是发送电子邮件、浏览网页并在网上购物,这些现象已经长远地影响到了网络架构的发展,也直接影响了 P2P 应用程序的发展。这种变化改变了人们使用网络的方式,出现了许多新的情况,例如网上协作的崩溃、防火墙的大量使用,产生了许多非对称的网络连接方式,比如说 ADSL 和 Cable Modem。

世界 90 年代末期,因特网发展的另一个趋势也对 P2P 应用程序带来新的挑战,那就是非对称网络连接的发展。网络供应商为了得到更高的效率而决定提供非对称的带宽,往往是下行带宽非常大而上行带宽非常小,ADSL 和 Cable Modem 的下行/上行带宽往往相差 3~8 倍。这种用法的根源在于 Web 是因特网的主要应用,绝大部分用户仅仅是 Web 的客户机,而不是服务器。即使有部分用户想发布自己的网页也不会通过家庭宽带连接的方式来实现,而是通过第三方提供的专用服务器来发布。

现在的问题在于 P2P 应用程序正在改变原有的假设:网络用户仅仅想从因特网下载东西,而不会上载信息。Napster 和 Gnutella 等文件共享应用程序颠倒了带宽的使用方式,使得计算机提供的文件比它下载的文件还要多,要求的上行带宽要比下行带宽大。但是现有的网络架构并不能很好地满足要求,而且更糟糕的是,由于 TCP 协议对速度的控制,一旦上行通路被堵塞,下行通路也会受影响,所以如果某台计算机正在通过慢速的上行通路给其它计算机提供文件服务的话,那它就不可能同时在快速的下行通路上下载文件。因此 P2P 应用程序在非对称带宽的网络并不能够很好地运行,一旦 P2P 程序广泛流传,网络基础架构就应该变得易于处理这种新的网络流量模式。

从 2000 年开始,一个能够在网上进行音乐文件共享的名为 Napster 的 P2P 程序在网上广泛流行,吸引了广大网上乐迷的注意力,短时间内就吸引了成千上万的用户,原因在于用户可以下载 MP3 音乐文件。Napster 应用模式与通过 FTP 下载文件不同,FTP 是把所有的文件都集中到服务器上,所有的拥护都到该服务器上下载文件,其缺点是当用户连线众多时会造成服务器工作繁忙、带宽拥挤、下载速度变慢,而且所共享的文件仅仅限于服务器上的文件;而 Napster 上所有的共享 MP3 文件都是由用户提供的,种类繁多,而且所有的文件都保存在用户的计算机上,Napster 提供了一个服务器来保存所有用户提供的 MP3 文件的目录以及其计算机的地址,当某个用户需要下载 MP3 文件时,他通过服务器查询到所需要的 MP3 文件所在的计算机地址的列表,由于同一个 MP3 文件在许多不同的计算机上都有副本,该用户只需要从任意一台计算机上下载就可以了。这种用户之间通过 P2P 的访问来进行文件共享的方式有许多优点,首先是不会有带宽问题,因为大量的文件数据都是通过用户之间的计算机来进行交换的,不存在集中的服务器的带宽拥挤问题;其次是共享的文件内容是无穷无尽的,因为每个用户都可以在自己的计算机上共享个人 MP3 音乐文件,非常方便,不需要把文件上载到 FTP 服务器上;再次是不需要一个庞大的服务器,充分利用了资源。因为一般的 FTP 服务器都需要有很大的硬盘来保存共享的文件,而 Napster 利用的是用户计算机上闲散的存储资源。Napster 也有服务器,但是其巧妙之处在于服务器上只保存共享文件的地址信息,所占用的存储资源相对很少,而把占据大量存储资源的 MP3 文件保存在用户的计算机上;另一个巧妙之处在于文件的交换是 P2P 方式的,不需要通过服务器尽心,解决了带宽拥挤的问题。但是,非常不幸的是,由于 Napster 共享的是 MP3 音乐文件,虽然其初衷是让音乐发烧友们交换合法的 MP3 音乐文件,可是这种行为最终触及了音乐唱片公司的利益,世界各大音乐唱片公司联合把 Napster 告上了法庭,而且由于 Napster 提供的服务上共享了 MP3 音乐文件的目录信息,此种情况作为重要论据使 Napster 在法庭上处于不利地位,导致最后的败诉。终于,风靡一时的 Napster 就此退出历史舞台,但是其巧妙的 P2P 应用模式和短时间内急剧增长的用户数量还是给人们留下了深刻的印象,为后续的 P2P 文件共享应用奠定了基础。

与此同时,QICQ 和 QQ 等国内外即时聊天应用也迅速在国内流行起来,个人拥有一个 QQ 帐户就相当于拥有一个手机号码一样,只要用户在自己的计算机上安装了 QQ 的客户端软件并进行登陆,就可以与因特网上任何一位安装有 QQ 客户端软件的拥护进行文字聊天。实际上 QQ 的实现机制与 Napster 系统非常类似,用户通过客户端软件把自己的帐号和计算机地址登记到服务器上,并通过服务器查找其他在线的用户帐号和地址,然后直接进行聊天。可以说,即时聊天是一种非常典型的 P2P 应用,而且在现实中也取得很大的成功,受到全世界许多用户的欢迎。

由于文件共享和即时聊天等 P2P 应用程序的成功,越来越多的程序员在因特网上开发他们的 P2P 程序,越来越多的用户在使用 P2P 应用程序。

应用程序的用武之地

现在,让我们来考虑一下今天的桌面计算机用户希望使用哪些不同类型的应用程序。除了 Web 浏览和办公软件外,桌面计算机用户还希望计算机能提供如下功能:

★ 管理和共享信息:这些信息包括用户希望与商业伙伴、朋友和同事共享的所有文件、文档、图片、音频、视频和电影等。通过信息收集和编排功能,更先进的共享机智机制能使一台计算机扮演通用任务管理器的角色------比如,Google.com 就是分布式任务管理器系统的一个例子,而 Gnutella 是个人 P2P 文件共享系统的一个例子。

★ 协作:PC 用户发现地址簿、日程安排、聊天和 E-mail 等软件工具提高了他们的工作效率。通过将桌面工具软件连接在一起使得协同工作的电子商务团体能形成灵活、强大而有效的工作小组,例如 Java 开发人员使用 OpenProject.net 协同工作。而在更大范围内,成千上万的用户使用实时通信工具,这可能是目前最为流行的 P2P 应用程序了。

★ 企业资源管理:企业内协同工作流程提高了由连接到网络上的桌面计算机系统所组成的企业网络环境的处理能力。例如,Groove 使得一个航空业制造商能将工作订单请求发送到伙伴公司,并将已经完成的请求从一个部门发送到另一个部门。

★ 分布式计算:通过分散化方法实现互联网健壮性理念的一个自然扩展是设计 P2P 系统,这个系统将计算任务转送到数以百万计的服务器上,而任何一台这样的服务器都可能是一台台式计算机。

尽管 P2P 还处在初始发展阶段,但已经出现了很多能满足用户所有上述功能需求的 P2P 应用程序。随着人们对 P2P 技术优越性认识的深入,将来可能会有更多的使用 P2P 技术开发的应用程序。

技术的动力

商业和技术方面的三个主要因素促使人们采用 P2P 技术。

★ 分散化:越来越多的企业已经通过采用灵活的企业结构实现了更高的效率和效益。因此,最近几十年中,企业领导人一直致力于企业的分散化。我们已经经历了从大型主机模型到客户/服务器模型,再到互联网计算模型的变迁,直到今天的 P2P 模型的变迁。这个发展趋势不可否认地实现了离散化和分布化。

★ 费用和效率:软硬件的价格会越来越低,而处理能力却会越来越高。能提高生产效率或软硬件使用率的新系统将成为企业投资的首选。P2P 具备充分利用以前未被利用的资源的能力。

★ 普及应用的计算:我们可以想象,信息系统在现代社会中无所不在:衣服、工具、汽车和设备,任何你能想象的东西中都存在着计算机芯片。信息系统不仅无所不在,而且它们之间是互连的。网络连接设备的市场一直在持续增长,而 P2P 系统正是被设计用于支持这个市场的。

随着企业逐步推进其电子商务进程,他们会更加深入地认识到连接交易流和通信流的必要性。同样,他们也会认识到为完成常规任务和特定任务而为合作者和外部伙伴建立"电子村落"的必然趋势。电子商务的发展将会造成更多的商业合作需求。P2P 技术天生就顺应了建立分布式和特定目的网络的发展趋势。

第二章 P2P 体系结构

使 Gnutella 和其他 P2P 应用程序变得有趣的原因是它们能非常容易地将由协同工作的节点组成的大型网络聚集在一起,并且这些节点遍布整个网络。这些节点是普通的 PC,它们动态地聚集在一起形成分布式的文件系统。这样形成的网络瞬息万变------很多节点位于防火墙和单向 NAT(Network Address Translation,网络地址转换)路由器之后;在非工作时间内,这些计算机可能处于关闭状态,并且这些计算机能随意地进入和离开网络。这种性质和网络组织结构是相互矛盾的,它更像我们在企业网上看到的典型的文件系统。

在客户/服务器模型中,由服务器控制和管理着客户端与其他资源,比如数据库、文件。网络和其他客户端的关系。在客户/服务器模式的网络中,服务器扮演着"高等公民"的角色。为了管理其"下属",服务器被赋予了特定的权限和功能。

对等节点的概念对我们设计和实现系统的方式产生了巨大的影响。在传统层次化系统中已经解决的问题又被重新 提起,在 P2P 的世界中,我们开始重新讨论和评价这些问题。

如何识别实体和确定实体的位置?谁来控制对资源的访问?尽管在任何环境中,这些问题都难以回答,但至少我们能很容易地理解这些问题。而在 P2P 系统中,情况并非如此。这是计算技术的新课题。规则未定,我们仍然有机会投身于 P2P 前沿领域的设计和开发中。P2P 技术可能是继 Web 浏览器之后传递互联网信息的第一次革命。

有趣的是单词"peer"的动词形式的意思是"凝视,仔细或困难地看"。当不再才用层次结构关系时,"peer"的这个意思正好可用于描述 P2P 节点所需的行为。

对等节点如何搜索自己的同伴并形成协同工作实体?P2P 的第一代应用程度就为解决隐含在这个问题中的困难而费尽周折。结果是这些应用程序暴露出了早期 P2P 系统的优势和不足。

通过研究 P2P 的早期系统,比如 Napster、Gnutella 和 Freenet,读者可以学到很多东西。这些应用程序显示了 P2P 系统的共同特征。P2P 系统包含了一个动态元件,这个元件能帮助这些应用程序形成和发展组和域。早期的 P2P 系统使用这个元件的主要目的是检索文件和解决 P2P 系统中的共同问题。

系统需要虚拟域名空间来增强当今的寻址技术。虚拟域名空间提供了一种永久识别节点(或服务)的方法,如果没有这种方法,那么 P2P 系统是不可能实现节点(或服务)寻址的。以读者的 E-mail 地址为例,不管读者使用何种计算机访问 E-mail,这个地址都唯一地识别了你的 E-mail 信箱。

就功能性而言,P2P 系统中的对等节点被认为是平等的。平等性意味着在网络中不再需要通信中间设备来帮助和参与节点间的通信。如果读者的计算机是连接到互联网上的,那么你的计算机就可以直接连接到 P2P 系统。

对等节点可以出现在网络上的任何地方。对等节点可以是普通 PC,也可以是你口袋中的掌上导航助手。如果将之连接到网络上,你就可使之成为对等节点。

对等节点不是稳定不变的,它们可以在网络上随意出现或消失。在很多 P2P 系统中,时断时续的连接是正常状态而不是非正常状态。早期的 P2P 系统是由拨号用户组成的。这些用户通过拨号方式建立连接,加入网络;然后断开连接并离开网络。对于这样的系统成员,P2P 系统中都有一个相应的帐号。

对等节点是很广泛的数组处理(计算)能力、带宽资源和存储能力。尽管 P2P 系统中的节点是对等的,但某些节点在性能上比其他节点更为强大。一台膝上型电脑可通过拨号方式连接到互联网并成为一个对等节点。而一台带光纤通道的 Sun Enterprise 10000 计算机也可是同一网络中的一个对等节点。从功能上说,这两台计算机是对等的,但它们之间的性能差别却非常之大。

系统正在改变我们设计能力充分利用整个网络资源的系统的方式。P2P 的这一特性将使我们受益非浅。

网络

Peer-to-Peer 网络是一种与传统的 Clien/Server 或多层服务器网络完全不同的网络体系结构。P2P 网络是由 Peer 组成的,根据 JXTA 的定义,任何一台能上网的机器都可以是一个 Peer,甚至计算机上的一个程序都可以成为 Peer。P2P 网络中的 Peer 是彼此直接通信的。这种通信无需依赖集中式服务器或资源就可完成。在 P2P 网络中,通过 Peer 之间的交互操作就可以完成工作,共享信息。通过创建有潜力展示非常高的可用性和容错能力的计算资源网络,P2P 体系结构使真正的分布式计算成为可能。

网络的一个非常重要的特点就是各个 Peer 彼此之间可以直接通信,至少是可以访问到的。在第一章中我们已经介绍,由于防火墙、NAT 和动态 IP 等原因,在现实的网络中有许多计算机是不能访问的,而在 P2P 网络中就必须解决这个问题。P2P 网络不是推翻现有的网络结构,而是在现有的网络上构建一个符合 P2P 特点的网络,但是又不限于现有的网络协议。如图 2.1 所示,中间黑线下面是现有的网络,网络中有许多计算机通过现有的 TCP/ IP 协议或者是 HTTP 协议进行通信;而黑线上面是一个虚拟的 JXTA P2P 网络,通过把黑线下面现有的网络映射成为 P2P 网络。另外,既然是在现有的网络上构建一个 P2P 网络,就必须考虑到现有网络上存在的多平台、多语言的情况。

虽然 JXTA 的第一个参考实现是基于 Java 语言的,但是从 JXTA 自身的设计来看,JXTA 程既不特定于 Java 编程语言,也不特定于 Java 平台。换句话说,任何人都可以在任何硬件平台上,用任何操作系统、任何编程语言实现基于 JXTA 的网络。正因为 JXTA 的这种平台无关性,它甚至不依赖于 TCP/IP(也就不会依赖现有的因特网架构,从而为 P2P 网络的构造打开方便之门),从而为我们提供了构建 P2P 体系结构的基础。从图 2.l 可以看到 JXTA 并没有依赖于某一种具体的网络和协议,之所以目前的实现采用 TCP/IP 和 HTTP,是为了与目前因特网架构兼容以及能与大多数防火墙协同工作。

网络应该具有下列特性。

★ 互操作性:P2P 系统应该能够使内部连接很容易地找到彼此,彼此间进行交流,加入基于团体的活动,提供无缝跨越不同 P2P 系统和不同团体的服务。许多现存的 P2P 系统仅能提供简单类型的服务,例如:Napster 提供音乐文件共享,Gnutella 提供通用文件共享,AIM 提供即时消息,由于这些服务的不同特性和通用的下层 P2P 结构的缺乏,每一个软件的零售商提供了互不兼容的系统,它们之间彼此不能相互操作。这意味者每一个零售商都创建了自己的 P2P 用户团体,更为重要的是,一个 Peer 如果要加人由不同 P2P 实现的多种团体,必须支持不同的 P2P 系统和团体的多种实现。

★ 平台无关性:P2P 系统应该设计成独立于编程语言如 C、Java 等,独立于系统平台如 Windows 和 UNIX,独立于网络平台如 TCP/ IP 和 BLUETOOTH。现在许多 P2P 系统通过在一定的系统平台上和一定的网络平台上发布一组 API 来提供特性和服务。例如,一个系统提供运行在 Windows 系统上、遵循 TCP/IP 协议的一组 C++API,而另一个系统提供了运行在 UNIX 系统上、遵循 TCP/IP 协议和 HTTP 协议的一组 C 和 Java 组合的 API。P2P 的开发者必须选择用哪组 API 来编程,目标是哪组 P2P 客户,由于两个系统之间没有互操作的可能性,如果开发者想要提供给两个团体相同的服务,他们必须为不同的 P2P 平台开发两次相同的服务或者在两个系统间架一座桥,考虑到已经存在的几十套 P2P 系统,两种方法都是效率低下和不切实际的。

★ 广泛性:P2P 系统应该设计成可以运行在任何有数字处理功能的设备上,包括传感器、消费电子设备、个人数字助理、网络路由器、桌面计算机、中心服务器和存储系统。

许多 P2P 系统,尤其是新兴公司提供的,倾向于选择微软公司的操作系统作为它们的目标部署平台,这种做法的原因是因为可以符合最广泛的安装基础以及获得最快的利润。这样不可避免的结果是对系统平台的依赖,这是在紧张的时间和有限的资源下工程的实现而不是技术设计的结果。

由于 P2P 并不定位在 PC2 PC 上,上述做法是没有眼光的。虽然最早的 P2P 系统演示在计算机系统的中心一 WINTEL 机器上,但 P2P 技术大规模的应用最可能发生在两个极端上------企业的大型系统和用户的小型系统。事实上,基于任何特殊硬件和软件系统之上的应用都经不起未来的考验。

因此,要构建一个 P2P 网络,必须考虑如下问题:

● Peer 如何找到其他 Peer?也就是 Peer 的发现机制是什么?

● Peer 之间如何传递信息?Peer 的通信协议是什么?

● P2P 网络与现有网络的关系?是完全推翻?还是可以利用现有网络来搭建 P2P 网络?

如何形成动态网络

动态网络是 P2P 系统存在的基石。互联网是带有某些静态特性的动态网络。例如,连接到互联网的任何计算机都被分配一个唯一的 IP 地址。

当今占统治地位的 IPv4 协议使用 32 位的 IP 地址。这种 IP 地址的表示方法是用点好隔开的十进制数字,例如 172.16.1.2。

这种地址模型限制了我们最终能使用的 IP 地址的数量。需要使用 IP 地址的计算机和设备的增长已远远超出了 IPv4 协议设计者们的预想。我们很快就会用完 IPv4 能提供的所有 IP 地址了。

现在,人们已经提出了 IPv6 协议。这个协议不仅大大增加了可用 IP 地址的数量,并且还能后向兼容 IPv4 协议。IPv6 使用 128 位的 IP 地址。IPv6 的 IP 地址的表示方法是用冒号隔开的十六进制数字。例如:FEDC:B978:7654:3210:F93A:8764:54C3:6543.IPv6 能支持 1012 台计算机和 109 个独立网络。但是,目前还不知道什么时候 IPv6 才能得到广泛使用。

因为我们更容易记住名字而不是数字,所以互联网提供了一种使用名字来识别计算机的机制。DNS(Domain Name Service,域名服务)提供了帮助用户识别计算机或将计算机名映射为 IP 地址的方法。因此,我们可使用 http://java.sun.com 而不是 http://72.5.124.55 来访问 Sun 公司的主页。

尽管我们使用 IP 地址和 DNS 来识别和寻址网络上的某台计算机,但 P2P 系统依然面临巨大挑战。使用 IPv4 能提供的有限的 IP 地址导致了寻址计算机的新机制。NAT 使我们能将一组保留 IP 地址分配给某个局域网上的计算机。当连接到互联网时,这些计算机共享一个"公共"IP 地址。因为保留 IP 地址组是为私有网络上的计算机预留的,所以这些预留 IP 地址不会出现在互联网上(即成为公共 IP 地址)。因此,这些 IP 地址可重用。尽管这些机制实现了 IP 地址的神奇转换,但也使得寻址实际的计算机地址变得更加困难,尤其在动态环境中更是如此。使用 IPv6 的新一代互联网的设计目的就是为了解决这一问题。但遗憾的是,这可能是未来几年之后才能实现的事。除 NAT 之外,互联网上 IP 地址的动态分配也非常普遍。这种分配 IP 地址的方式本身就为寻址计算机带来了问题。

系统如何识别其标志不断变化的对等节点?P2P 网络必须能唯一地标志该网络上的多有对等节点和可用资源。因此,P2P 系统必须定义自己的独立与 IP 地址和 DNS 的命名规则。为了使 P2P 系统上的用户拥有自己的永久标志,P2P 系统必须创建虚拟名字空间。

不同于 DNS 等寻址方法中采用的预定义或预配制方式,P2P 系统网络中的对等节点通过使用 IP 地址或 DNS 作为导航助手来相互寻址,从而形成动态或虚拟网络。形成动态网络是 P2P 系统的典型特征。

寻址 P2P 系统中的对等节点和资源

关于在 P2P 系统中如何寻址节点和资源的问题,已经见诸于大量的出版物并引起了广泛的讨论。时至今日,这个问题的解决已成为成功的 P2P 系统的重要标志。

读者可从两个层次来思考寻址问题。首先,寻址过程和发现一个对等节点相关。这里所谓的对等节点是指可能理解节点间交换的协议信息的信息处理实体。这个信息处理实体和其他实体使用同一种语言,并且该实体能理解这种语言的语义。对等节点的寻址目的是需要找到某项服务或帮助,并克服很多与信息处理相关的问题。如果对等节点不理解相互交换的信息,那么它们就无法处理相互交换的大量数字信息。

寻址的第二个层次与用户发现自己感兴趣的资源相关。早期的 P2P 应用程序是用于处理文件共享和文件检索的。与流行的搜索引擎不同,P2P 应用程度采用了新的技术来检索互联网上的文件和信息。

传统的信息检索技术已经无法容纳互联网上以指数形式增长的海量信息了。尽管流行的搜索引擎都支持并行计算机制,但发现可用信息的时间延迟却在持续增长。P2P 为互联网上的信息检索提供了一种更加实时化的资源寻址方法。但寻址技术和所需协议的代价也是非常昂贵的。

有人对 Gnutella 软件的遭遇做过详尽的记载。如图 2.2 所示,作为流行的文件共享和搜索程序,Gnutella 没有采用传统的广播机制来寻址对等节点。广播次数的增长非常之快------用户越多,广播越多;当用户基数增长太快时,网络系统将因崩溃而停止运行。与此同时,大量的 Gnutella 请求将阻塞网络。Gnutella 的成功之处在于它注意了对寻址结构的限制。

图 2.2 一旦网络增长超过预期,Gnutella 将很快遭遇"广播风暴"

对于成功设计和实现基于对等节点的网络,一种有效的寻址机制是至关重要的。为了提高寻址效率,这种寻址机制必须在不同的运行环境中保持高效率。不管网络规模多大,这种寻址机制都必须能迅速寻址到对等节点和相应资源。另外,这种寻址机制还必须有足够的灵活性以防范黑客攻击和安全入侵,否则这种寻址机制的可行性将受到严重质疑。

当把集中化系统的寻址机制用于基于对等节点的大型网络时,这些寻址方法往往无能为力。集中化系统的寻址方法要么缺乏可扩展性,要么会在系统中产生单点错误。

现在业界已经开始使用多种采用不同结构和设计的分散化的寻址方法。这些方法各有千秋,因此特定的方法往往只适合特定的环境。但在基于对等节点的大型网络中,这些方法都有不足。

简单广播

简单广播将一次请求发送到同一网段中的所有节点上,当将简单广播作为寻址方法时,简单广播能找到大量可能存在的对等节点或发现大量资源。这种方法的不足之处在于:当用户基数线性增长时,广播请求的数量将以指数方式增长。

这种方法可能会导致对网络带宽的巨大需求。某些情况下,广播请求将阻塞网络,并引发超时和数据重传,这将使本已不堪重负的网络带宽更是雪上加霜。同时,网络中还存在安全性问题和拒绝提高服务的可能。一个怀有恶意的对等节点可能会通过引发与用户基数不成比例的大量广播请求来阻塞网络。这将中断网络运行并降低网络效率。因此,简单广播只适用于小型网络。

选择性广播

简单网络的改进版之一是选择性广播。选择性广播不会将广播请求发送到网络中的所有对等节点,而是根据用户提供的限制性条件,比如节点提供的服务数量、内容可用性或信任关系等,选择相应的节点发送广播请求。但这种广播方式需要系统保留有关节点通信的历史信息。

寻址请求被发送到选中的节点。用户可根据自己定义的对等节点间的连接标准来估计目标点节点的响应时间。例如:用户可能只将寻址请求发送到其支持的带宽请求不低于某个最小值的对等节点,或将对资源的请求只发往可能包含该资源的节点。当然,如果用户需要了解的对等节点越多,系统的动态性就越小。如果不通过某种方式降低网络中的固定关系和静态关系,那么 P2P 的优势很快就会丧失殆尽。

选择性广播中仍然存在安全性问题。为了使选择性广播有效运行,非常重要的一点是使所以的对等节点都成为知名节点。

适应性广播

和选择性广播一样,适应性广播的目的也是尽量实现网络连接最大化和带宽使用最小化。选择标准可通过对网络环境的深入了解得到加强,例如用户可制定寻址操作中可使用的内存和带宽限制;通过预定义资源限制水平,用户可在寻址或资源搜索操作所使用的资源超过这个限制条件时限制该操作的运行,从而达到控制寻址和资源搜索所占资源的增长。这将确保网络不会因为故障元件、误操作的节点恶意攻击而消耗大量资源。适应性广播需要使用一些监控资源,比如对等点标识、消息队列尺寸、端口使用情况和消息尺寸及消息频率等。适应性广播能降低某些对网络安全的攻击,但不能完全消除攻击。

资源寻址

资源寻址和节点寻址密切相关。这两者的不同之处在于节点拥有信息处理能力(智能化设备)。对等节点能通过程序接口参与信息处理的过程。与对等节点相比,资源的静态特征更为显著,并且资源所需的仅仅是识别该资源的标识而已。资源寻址可通过集中或分散化检索方法实现。在同样开销情况下,集中化检索方法能提供良好的性能。满足大型对等网络硬件和带宽要求的费用可能会很高。但有一点,在某些情况下,不管使用多少软硬件。集中化检索方法都会在可扩展性问题方面遇到困难。分散化检索方法力图克服集中化检索方法在可扩展性方面遇到的问题。为了提高分散化索引系统的性能,存储在系统上的所有文件和文档都被分配了一个唯一的 ID。这个 ID 的目的是识别或定位资源。分散化系统能很容易地将资源 ID 映射为资源。Free Net 软件采用了这种资源检索方法。这种方法的不足之处在于对资源的检索必须十分精确;任何资源都必须有唯一的标识。分散化索引系统的另一个问题是持久保存缓冲信息。索引能在很短时间内失去和资源的同步。因为对等节点能随意进入和离开网络,而且索引种的资源也变化不定,所以对等网络非常不稳定。让所有因素保持同步和有效分布资源所引起的开销是分散化索引系统在可扩展性方面遇到的主要障碍。

因为对等网络如此不稳定,所以要知道一个节点何时处于在线状态需要开发高效的以用户为中心的分布式系统。虽然这种系统对网络环境的影响程度与具体的应用程序相关,但读者必须理解这两者之间的关系。

节点自制

系统是高度分散化和分布化的系统。现在我们已经非常了解分布式系统的优越性了。当你需要升级系统以便为增长的资源需求提供支持时,往往需要采用分布式处理系统。你还可能因为地理原因采用分布式系统,其目的是将资源和程序放到离其访问节点更近的地方。采用分布式系统的另一个原因是提供更高的容错能力和网络灵活性以及支持资源共享和增加协作性。

分散化系统提高了节点的自治能力。在 P2P 系统中,节点是高度自治的。对等节点是独立的并实行自我管理。前面已经提到,在客户/服务器模型中,服务器控制和管理着客户端与资源,比如数据库、文件、网络以及该客户端和其他客户端之间的关系等。对网络环境的操作、管理和监控而言,这种模型有着多方面的优势。集中化系统的优势之一在于集中化的监控和管理,可以从中心节点实现对资源的安全性保护,可以通过使用附加功能来弥补网络物理拓扑结构上的不足。例如,服务器可作为敏感技术资源的网关。

分散化系统对网络的管理更加困难。在分布式系统中,往往不能及时发现故障元件。更糟的是,部分故障产生后果和副作用是网络和应用程序无法处理的。我们可能无法估计由远程通信产生的响应时间和延迟效应。网络的状态可能时好时坏。过于频繁的网络错误和网络超时会使对等节点的通信很不稳定。同步化操作将使带宽资源更为紧张。

任何基于分布式系统的解决方案都应该减少或完全消除这些因素。P2P 系统是建立在这样的假设基础上的;网络提供的服务是分布式的且网络是不稳定的。不同的 P2P 系统采用不用的方法处理网络的不稳定性问题。

系统中的对等节点既能提供服务又能接受服务。P2P 系统中没有客户端和服务器角色的区别。任何对等节点都能提供服务或寻址一个能提供该节点所需的服务的对等节点。当一个对等节点请求服务时,可将其看成客户端;反之,当一个节点向其他节点提供服务时,可将其看成服务器。

对等节点常常用于需要高度并行化的系统。并行化方法并不是计算机领域内的新事物。事实上,现在进行的很多计算都是以并行化的方式实现的。多处理器计算机和操作系统依靠其并行处理能力执行任务。线程控制机制使我们能够将同一进程分配给不同的任务。然而,直到今天,并行化方法也没能成为应用程序开发中的普遍方法。尽管应用程序被设计成多线程的,但一般而言,这些线程都和控制一个进程所需的不同任务有关,比如从一个速度很慢的设备上读取数据或等待网络响应。我们并没有在并行环境中定义多个应用程序来执行相同的任务,比如检索一个大型数据库或以并行方式过滤大量信息。

对很多重复性任务,并行机制为我们提供了一种分而治之的解决方案。SETI(Search Extraterrestrial Intelligence,搜索外太空智慧生命)@HOME 工程表明,可通过互联网将个人计算加连接起来,以便为我们提供超级计算能力。SETI 工程检查来自外太空的电磁信号,希望能够发现其他星球上的智慧生命。这个工程需要花费大量计算资源来分析所获得的数据以及完成相关计算。这个工程的自愿者们从 SETI 的 Web 站点上下载了一个屏幕保护程序。这个屏幕保护程序能请求由分解 SETI 收到的大量电磁信号形成的工作单元。在这个工程启动的第一周内就有 200 000 人下载了这个软件。到 2000 年为止,参与这个工程的人数已经达到了 2 400 000 人。这种网络形成的计算能力超过了由 IBM 制造的,当时处理速度最快的超级计算机 ASCI White 的处理能力。P2P 系统的设计目的正是为了迎合这种分而治之的解决方案的增长趋势。

SETI 程是一种典型的系统结构,这种结构需要某种程度的集中化或协作机制。我们可根据拓扑结构来对网络进行分类。这里,网络拓扑结构是指节点在网络上的基本排列方式。目前有多种不同的网络拓扑结构供网络设计人员选择。

分散化拓扑结构往往采用一个集中化部件来提高其性能,这就形成了一种混合模型或称之为杂交模型。在 Napster 软件中,正是集中化的文件索引部件提供了该软件的文件识别和定位功能。而在 SETI 中,是由集中化的任务分发器来分配工作单元的。

支持混合模型

现在很多的 P2P 技术都采用一种支持混合模型的基于网络的计算模型。关键部位的集中控制节点提高了以分散化模型占统治地位的系统的性能。为提高 P2P 系统的关键性能特性,比如寻址和资源管理等,这些混合模型中定义了一些集中化控制点。混合模型还能提高系统的可靠性和容错能力。

为了理解 P2P 系统的实质,让我们先来回顾一下有关网络拓扑结构的知识。这些知识也有助于读者明白在设计 P2P 系统时,我们有多种不同的网络拓扑结构可供选择。任何类型的网络拓扑结构都不可能适用于所有的 P2P 系统。MIT 的 Nelson Minar 推荐读者应当从逻辑角度而不是物理角度来看待网络拓扑结构。换句话说,我们应当将这些网络模型看成是描述信息流向的术语,而不是将其当成网络物理连线的术语。

下面我们将逐一介绍 5 种常用的网络拓扑结构:

◎ 星型结构;

◎ 总线结构;

◎ 环状拓扑结构;

◎ 层次结构;

◎ 网状结构。

星型结构

星型网络将各个设备和节点连接到一个中心控制点上。所有的网络通信都经过这个中心控制点。与其他绝大多数的网络拓扑结构相比,星型结构更容易定位故障元件。如图 2.3 所示是一个典型的星型结构网络。

图 2.3 星型网络拓扑结构有一个用于通信控制的中心点

Napster 软件的文件索引就类似于星型拓扑结构。当然,使用中心通信控制点就意味着系统存在单点错误。在 P2P 系统中,单点错误可能会造成灾难性后果。

总线拓扑结构

总线拓扑结构将所有设备或存储介质都连接到相同物理介质上。总线拓扑结构没有中心控制点,而是使用了一条所有节点共享的总线。如图 2.4 所示,这条总线就是用于连接网络上的设备的。

图 2.4 总线拓扑结构网络没有中心点,每个节点都检查

总线上的信息,以确定该节点是否是该信息的目的节点

总线拓扑结构没有星型结构中由中心控制点导致的单点错误问题,但通信总线的问题将会影响生个网络。

环状拓扑结构

如图 2.5 所示,在一个环状拓扑结构中,任何一台设备或一个节点都被连接到其他两个节点上,形成一个回路。在这个回路上,数据信息到达其目的节点之前,将沿同一方向从一个节点传递到相邻节点。因为环状结构上一次请求传播的距离是确定不变的,所以可以预测请求在回路中的响应时间。

  • 图 2.5 环状拓扑结构没有中心点,消息从一个节点
  • 传递到另一个节点,直到找到目的节点
  • 环状网络也会面临单节点故障导致整个网络崩溃的问题。
  • 层次型拓扑结构

图 2.6 所示是一个层次型拓扑结构的网络。层次型拓扑结构和一个级联式的星型拓扑结构非常类似。换句话说,许多节点都连接到一些单一节点上,然后这些单一节点再连接到其他单一节点。这些星型结构的网络形成父子关系或形成类似于一颗倒置树的网络。

图 2.6 层次拓扑结构类似一棵倒置的树,任何一个

节点都是其直接相邻的下一级节点的中心控制点

网状拓扑结构

如图 2.7 所示,网状拓扑结构需要所有的网络设备或节点都有连接到该网络上其他所有设备或节点的专用连接路径。

  • 网状网络拓扑结构类似于互联网路由拓扑结构
  • 典型情况下,这种网状网络具有很好的灵活性,其原因是这种网络的任何两个节点间的通信路径都不止一条。但是,网状拓扑结构网络的容错能力取决于该网络中通信路径的完整性。
  • 混合模型

我们将要讨论的绝大部分系统都远比前面介绍的这 5 种网络拓扑结构复杂。实际上,很多系统都是由多种网络拓扑结构组成的。这些不同的网络结构将对一种或多种网络模型进行补充或扩展。例如,在 Napster 中就有一个集中化的文件索引节点,如图 2.8 所示,该系统中的文件传输和转换部件类似于采用网状拓扑结构的点到点连接网络。

图 2.8 Napster 代表了一种 P2P 混合拓扑结构,在这种结构中某些

功能是集中化的,而另一些功能是高度分散化的

第三章 JXTA 技术

虽然目前世界上已经存在了许多 P2P 的系统,但是从研究角度而言,Sun 公司于 2001 年推出的 JXTA 技术无疑是进行 P2P 研究的利器。JXTA 名称的含义代表 Juxtapose 工程。Juxtapose 的中文意思是并列,JXTA 并不认为因特网(Internet)或内联网(intranet)中现有的 Clien/Server 计算模式会消失或被取代。相反,JXTA 技术将作为一种补充,与这些技术共存(因此是并列的),并给最终用户带来超值体验。因特网和内联网的用户将能够从网络的这两种计算形式中获益。

JXTA 是什么

首先,JXTA 是为了构建 P2P 网络而制订的一组协议,是解决了上述构建 P2P 网络所碰到的问题的解决方法。JXTA 标准协议规范介绍如下: "JXTA 由六个协议组成,这些协议是专为特定的、分布式的、对等的网络计算而设计的。使用这些协议,Peer 可以互相合作来建立自我组织、自我管理的对等组,而不必关心它们在网络中所处的位置(在网络边缘或者防火墙的后面),并且也不需要集中的管理机构。"

因此 JXTA 的核心是六个协议。

其次,JXTA 是 P2P 应用程序开发的运行平台。目前 JXTA 首先推出了基于 Java 的参考实现,提供了支持六个协议的 Java API,JXTA 还将推出包括 C 语言在内的其他编程语言的 API.

JXTA 在设计时有如下几个目标:

操作系统无关

语言无关

为 P2P 应用提供服务和基础

从本质上讲,JXTA 的目标是希望在任何设备,从台式机到 PDA、汽车、洗衣机等设备都可以支持 P2P 编程。这里有几个概念上的目标,它们包括:

  • 使用组来组织 Peer 并且在组内提供服务和应用的环境。
  • 组可以使用认证和验证方式来控制组内的访问权限。
  • 通过网络来发布关于 Peer 和网络资源的信息。
  • 通过系统来发布各种请求。
  • 提供一个基础平台,供 Peer 之间做路由和通信。在防火墙或者其他障碍后面的 Peer 之间的通信也是这个目标中很关键的一部分。
  • 提供一种机制允许 Peer 之间可以彼此监视状态和资源。

除此之外还有一些其他目标,例如加密、支持不同的通信协议、易用性、稳定性和性能等。所有这些目标在设计 JXTA 协议和最初的 Java API 时,都被考虑到。

另外,开发人员和 Sun 公司的管理者还考虑了以下目标:

  • 系统应该允许任何设备直接加人到 JXTA 网络中去。
  • 系统应该允许 ISP 对网络上的 Peer 进行集中管理。
  • 系统应该支持数字产品版权的管理,例如购买的软件、音乐 CD、电影等。
  • 封装和抽象一些特定的核心功能,以便产生出商业方面的应用。

从上面列出的目标可以看出两点,首先要让企业觉得使用 JXTA 可以使自己对系统进行控制,原因在于大部分 P2P 系统没有集中式的管理,所以在应用中不受企业的欢迎。其次,对于硬件或者软件提供商来说,JXTA 系统需要能够创造出利润。

根据以上这些目标,JXTA 被设计成企业可以接受的、容易维护的、健壮的,并且能够满足任何 P2P 应用的概念。

JXTA 提出了一些新的概念,例如 Peer(对等机)、Peer Group(对等组)、Pipe(管道)和 Endpoint(端点)等。JXTA 在做对等通信和发现的时候,使用了一个新的概念 Advertisemen(广告),这是一个 XML 文档,它描述了 JXTA 网络上可以获得的服务和信息。最后,还需要一些不同类型的标志符来区分不同的项目和服务。

在 JXTA 中,XML 是大多数协议的基础。因为它能被任何语言读取,并且其合法性可以验证,而且 XML 也被广泛地应用。使用 XML 格式来创建一个协议是个很好的选择;因为如果使用二进制格式会很难理解,而且解析起来很费力气,而使用 XML 格式,有很多解析器可供使用,既有商业化的,也有免费的。并且,XML 正在成为一种标准被许多厂商采用以表达数据。

当然使用 XML 也有它不利的一方面,XML 并不是一种压缩的数据传送方式,用 XML 编写的信息往往比由二进制编写的信息大得多。虽然也可以采用一些技术来加以改善,例如用二进制信令来替代 XML 的标签,或者是进行数据压缩,但是这些技术在目前还不是被广泛接受的标准,因此在 JXTA 中还没有采用。最终,JXTA 的核心开发人员创造了一种简单的二进制信息传送方式,并使用简洁的语言和缩写来描述标签名字,但是这也意味着 JXTA 中采用的 XML 是不容易读懂和学习的。

JXTA 由三层组成,如图 3.1 所示。第一层是 JXTA 核心层,它包含了服务所需要的核心功能;第二层是服务层,它提供了访问 JXTA 协议的接口;第三层是应用层,它使用服务来访问 JXTA 网络和 JXTA 提供的功能。这样的设计和一个标准的操作系统比较相似,标准的操作系统包括核心操作系统、服务和应用程序。

图 3.1 JXTA 的三层结构

各层的说明如下所示。

核心层(JXTA Core):这一层封装了最根本的东西,包括 Peer、对等组、Peer 发现、PeeR 通信、Peer 监视和相关的安全原语。

服务层(JXTA Services):这一层包括对于 P2P 网络不是必需的、但很通用的功能,如查找、共享、索引、代码缓存和内容缓存的机制。

应用层(JXTA Application):这一层包括了应用 JXTA 服务开发出来的完整的 P2P 应用程序,例如 myJXTA,JXTA-CAD 等应用程序。

JXTA 的概念

在 JXTA 网络中,有一些概念是需要熟悉和理解的,它们是从 JXTA 协议中提出的一系列的专有名词。

eer(对等机)

Peer 是一个虚拟的通信点。在一台计算机或者设备上可以有很多个 Peer。一个 Peer 并不是一个用户,因为一个用户可以有多个 Peer,同一个设备上也可以有多个 Peer(在测试的时候经常用到)。因为 Peer 不等同于用户,所以需要将用户和 Peer 抽象出来并分离开。

Peer 与特定的网络服务联系得很紧。在 JXTA 的参考实现中,Peer 可以使用网络提供的基本服务,例如 rendexvous(集合点服务),router(路由服务),gateway(网关服务)等。这些基本服务又可以提供搜索和通信服务。一般来说,并不是所有的 Peer 都使用这些服务,它们只使用这些服务的一部分。

eer Group(对等组)

对等组是一种组织 Peer 并且发布组内的特定服务的方式。对等组可以被创建、加入和退出。在一个组里还可以更新一个组成员的关系。由于一些原因,对等组需要对成员关系进行一些限制,例如为了通信的安全、隐私的考虑等。这里使用一种协议来认证,它专门收集信息并判断其是否符合成员关系的要求。

对等组为应用程序提供了一种环境,例如对某个话题感兴趣的 Peer 可以组成一个组,并且在组内使用一个聊天服务来讨论。这样,聊天的信息就会限制在那些加人到这个组内的成员之间。并且,对于想加人到这个组的 Peer,可以使用成员 ID 来进行认证;没有这个 ID 的 Peer 不能够加人到组内,也就不能够使用组内的聊天服务。

也可以把对等组看成一个虚拟的私人网络 VPN。一个 VPN 只允许几个计算机之间互相交流,而不允许因特网上其他的成员加人。由于 VPN 使用了加密的方式,对于偷听者他们不能够理解组内的谈话。对等组也可以限制 Peer 的加入,同样也可以对谈话消息加密。

Endpoint(端点)

在 JXTA 应用中,端点是最基本的通信方法。一个端点就是实现了特定通信协议的 Peer 的地址。一个 Peer 可以有多个端点,这样可以通过不同的协议来与其他 Peer 通信。

端点不一定要是物理地址,端点可以允许物理地址发生变化。端点的一个简单例子就是一个 IP 地址加上一个端口。通过使用这些值,可以打开一个流并且与目标 Peer 通信。然而,JXTA 在流的基础之上又放置了一层,称之为 Pipe(管道)。这样,不是将一个流连接到一个地址,而是把一个管道连接到端点上。端点和管道的好处在于,不用去关心 Peer 所使用的真正的地址和协议是什么。使用抽象出来的端点和管道,可以为创建 P2P 应用提供强大的功能并降低复杂性。

由于管道使用通信协议来连接,端点描述了协议和连接的所需要的信息。因此端点可以描述 HTTP、TCP、BEEP 以及其他可以支持的通信协议。

一个 Peer 可以支持一个或者多个端点。通过使用多种协议,Peer 可以提供更有效率的方法。也就是说,如果两个 Peer 都在防火墙的后面,可以直接通过它们的 TCP 端点来通信;如果两个 Peer 要穿过防火墙去通信,则需要使用 HTTP 的端点。

Pipe(管道)

管道是 Peer 之间的虚拟通道。通常,我们认为对等通信是单个的通信连接,但是也并不是总是这样的。因为防火墙和其他障碍的存在,许多 Peer 并不能直接连接。这时,管道更像一个在多种通信协议之上的虚拟层,可以通过起网关作用的 Peer 对通信提供中继支持。

管道是 JXTA 最基本、最重要的特性,它提供了一种很好的方案,使得 Peer 在大多数网络情况下都可以通信,而不用去管防火墙或者其他的障碍。即使你不知道另外一个 Peer 的位置以及它所使用的协议等信息,通过管道仍然可以与之通信。

管道作为一种抽象的方法,隐藏了一些细节,比如在多个连接的时候可能会有多个 Peer 参与进去。管道也可以重新定位,找到原来的 Peer。在 JXTA 的参考实现中,有几种常用到的管道,它们是:

  • 单向异步------这种管道只用来做单向通信。管道是异步的,消息到达时可能不是顺序的。这是 JXTA 平台上最基本的一种类型的管道。
  • 同步的请求/应答------所有发出的信息都会收到一个应答消息,消息到达的顺序是按照它们发送时候的顺序。

*成批发送------用来发送大量的数据。

*流传送------通过流可以更有效地传送诸如声音、视频等大量的数据。

*双向------它是两个单向异步管道的组合。

*单向同步------所有发出的信息都会收到一个应答消息,消息到达的顺序是按照它们发送时候的顺序。

*单向可靠安全的管道------所有发出的信息都会收到一个应答消息,并且这些消息都是加密的。

管道还可以分成以下两种类型:

*点到点类型------点到点的管道连接两个不同的 Peer。可以使用多个起网关作用的 Peer 来创建连接。

*传播类型------将一个 Pee 连接到多个目标 Peer。

现有的 JXTA 参考实现已经提供了单向异步管道、单向可靠安全管道和双向的管道。

JXTA 和传统的网络是非常不同的。大多数网络协议或者没有地址,或者有一个固定的地址。而 JXTA 抽象出一个概念叫做端点,用来作为地址。一个 Peer 可以有多个端点。Peer 可以通过一种或者多种协议例如 TCP、HTTP 等进行通信,所以可以使用多个端点。JXTA 使用多种传输协议的目的是为了在与其他 Peer 通信时可以选择最好的方式。

如果一个 Peer 在企业的防火墙的后面,可以使用 HTTP 来与防火墙之外的 Peer 通信,还可以使用 TCP 来与防火墙内局域网内部的 Peer 通信。通过灵活使用多个传输端口,对特定的 Peer 使用特定的协议,以得到最好的速度和响应。

Advertisement(广告)

一个广告就是一个 XML 文档,它用来描述 JXTA 的消息、Peer、对等组或者服务等。广告都遵守编码、标签和内容的标准。广告用来交换 JXTA 网络上可以获得的任何信息。例如,一个 Peer 创建了名称为"MyChat"的对等组后,就可以使用 IP 多播方式把广告发布到本地的 JXTA 网络。也就说,子网中的每一个 Peer 都会收到一份广告的副本,此外广告还会被发送到集合点去。

Peer 使用一种叫做集合点(Rendezvous)的特殊 Peer 来发现网络上其他地方的广告。

集合点 Peer 可以存储广告并且支持搜索。Peer 可以使用对等组的名字或者其他属性来搜寻该对等组广告。有了对等组的广告,其他的 Peer 就可以使用广告中的 XML 来实例化并加人到"MyChat"这个对等组中。一旦成为对等组的成员之后,Peer 可以使用对等组的环境所提供的服务。

广告实际上是 P2P 网络中的"名片",P2P 网络中的任何资源,包括 Peer、对等组、管道等都可以用广告来描述,目前是在 P2P 网络中标志资源,并且可以相互找到。

大多数 JXTA 广告的编码是使用 UTF-8,它是对 Unicode 的一种 ASCll 编码方式。UTF-8 使用的是 8 位编码,Unicode 使用的是 16 位编码,因此可以节省一半的空间。只有在消息体中间可能会使用到完全的 Unicode 编码,在消息体里可以指定使用 Unicode 或者其他的字符集作为编码方式。

Message(消息)

在 JXTA 中,有两种方式来处理消息。一种是使用 XML 格式,数据都遵循 XML 标准被包装到消息里;另外一种是使用二进制格式。尽管希望对所有的 JXTA 消息都使用 XML 格式,可是由于大量的消息需要传送,使用 XML 格式的消息会导致效率较低,而且由于消息通常是在程序之间传送的,所以可以规范的消息内容使用二进制的格式;对于其他的仍然采用 XML 格式。

在一个 XML 协议中使用二进制消息看起来似乎不太合理,但事实上使用二进制消息,除了可以得到紧凑的格式之外还有很多其他优点。首先数据可以使用一些标准技术进行压缩,对文本等数据的压缩可以节省大量的传输时间;另外,许多消息本身就是二进制的格式,例如文件共享程序中共享的文档可能就是二进制的,因此可以直接使用二进制的格式;还有一个问题就是加密,为了加密可以把数据转化成为二进制,然后直接使用二进制的消息来传输。

Rendezvous Peer(集合点)

一个集合点首先是一个 Peer,而且是一个能够处理来自其他 Peer 请求的 Peer。集合点也可以将请求委托给其他 Peer,当然那些 Peer 也必须是集合点。使用集合点的一个主要目的就是为了方便在本地网络之外搜索广告。集合点通常拥有更多资源,并且可以存储大量的有关它周围 Peer 的信息。

集合点也可以作为搜索的传递者。集合点可以转发发现请求到其他的集合点(原集合点通过与其他 Peer 的广告交互而得到了被转发集合点的信息)。每一个集合点如果本身没有被请求的信息它都会转发该请求。

IP 多播(IP Multicast)是一个一到多的消息传输协议。IP 多播用来发送数据的副本到一组地址。在 P2P 应用程序中,IP 多播有两个好处。首先,因为多播使用一个组地址而不是使用 IP 地址,一个 Peer 可以在不知道接收者地址的情况下发送消息。这样做的结果是在多播网络中的所有 Peer 都可以响应发出请求的 Peer,将有关查询的结果信息、甚至是自己的 IP 地址(用于与请求 Peer 直接通信)发送回去。

IP 多播的第二个好处是减少使用带宽。因为所有的 Peer 都可以看到一个单一的消息,没有必要向每一个 Peer 发送消息的一个副本。当发送大量的数据到一组 Peer 时,这一点是非常重要的。

使用多播的一个缺点是一些防火墙和路由器会阻塞多播的消息。在因特网提供商之间通过因特网主干网可以支持多播消息,不过这种服务是需要额外付钱的。还存在其他 IP 多播的障碍,比如个人防火墙、子网路由器。这就是为什么 JXTA 不是仅仅支持 IP 多播的原因。

一般情况下,只要在防火墙后能够支持多播对于大多数的 P2P 网络就足够了。你可以这样来利用本地的多播,先将消息发送到每一个网络的某一个特定的 Peer 上,然后该 Peer 又通过本地的多播将消息发送给本地的 Peer。

只有集合点允许进行超出局域网的搜索。一个 Peer 可以选择成为一个集合点,但这不是必须的。作为集合点好的一面是集合点可以以缓存的形式保留从其他集合点得到的查询结果的副本;不好的一面是,该 Peer 将占用很多的内存和带宽。由于请求数量可能很多并且大量的广告数据会消耗很多的计算机资源,在这种情况下我们可以选择将计算机作为专用的集合点。集合点同时可以作为企业内部网的网关和路由器,其效果和使用传统的路由器是一致的。在每一个子网内也需要使用一个集合点。

是否选择使用专用的集合点 Peer 取决于安全性的要求和使用的 P2P 应用的范围。P2P 网络的拓扑结构需要通过多个的例子来进行测试并且需要定期监控。特别要注意的是:当 P2P 网络的服务在大量 Peer 上存有副本时,P2P 网络的效率更高。有些时候并不是额外的集合点就可以提高网络的效率。

当一个 Peer 在搜索广告时或者是其他服务使用集合点机制来路由消息时,集合点才被使用,因此一个 Peer 对集合点的需要不是持续的。为了能够更好地发挥作用,一个连接到因特网的集合点最好尽可能地暴露给网络上的多个 Peer。在防火墙内把所有的 Peer 都配置为集合点不一定能够发挥很大的作用。

Router Peer(路由 Peer)

JXTA 中的一个路由 Peer 是一个支持 Peer 端点协议的 Peer。不是所有的 Peer 都需要实现该协议,因为和传统的网络路由器一样,我们只需要少数几个路由器去支持一个大网络。JXTA 路由器和传统的路由器非常相像。最主要的区别是 P2P 不是非常固定并且包括了很多非静态地址。

Gateway Peer(网关 Peer)

JXTA 中的一个网关 Peer 是一个作为通信中继的 Peer。网关 Peer 和集合点的不同之处在于,网关是用来在 Peer 间传递消息,而集合点是用来传递请求的。

网关 Peer 就像是无线电转发器或者说是 Peer 间的一个中介,它传递消息。因为有防火墙、NAT 设备和代理服务器的存在,网关对网络的连通具有决定性的作用。网关可以存储消息,并且等待希望得到这些消息的接收者来收集它们。

网关的存在是因为因特网非常混乱。混乱的原因是有各种各样的用于防止 Peer 间通过公用访问方法通信的安全保障和障碍物,另一个原因是各个 Peer 所支持的协议是不同的,一些 Peer 可能使用 TCP,另一些可能使用 HTTP。在无线情况下,我们需要使用无线应用协议(WAP)。网关尽可能多地支持这些协议,因此它可以作为不同类型协议间的中介。JXTA 目前支持 TCP 和 HTTP,不过对其他协议的支持正在开发中。

在因特网上同关是与大多数安全机制交互的关键。防火墙、代理服务器和 NAT 设备是主要的安全屏障。图 3.2 说明网关 Peer2 是怎样作为 Peer1 和 Peer3 之间的交互接口的。网关将从 Peer1 来的 TCP 消息转换成 HTTP 消息传递给 Peer3。当消息从 Peer1 发出时,是通过 TCP 发往网关 Peer2,网关 Peer2 存储了这个消息,直到 Peer3 向它发出获得消息的 HTTP 请求。

图 3.2 通过网关对等机进行 Peer 间的通信

用于通信的 Peer

从上面的概念介绍中我们可以得知,P2P 网络中有一部分的 Peer 和普通的 Peer 的功能是不太一样的。虽然 P2P 网络希望每个 Peer 之间都可以进行通信,但是在现实的网络中实际存在着许多情况导致计算机之间无法相互直接进行通信,所以需要在 P2P 网络中从概念上就抽象出一些特殊的用于通信目的的 Peer,包括路由 Peer 和网关 Peer。

接下来的部分将讨论现实网络中阻碍 P2P 网络通信的每一种障碍,每一种障碍都需要我们对网络进行抽象,建立一个 P2P 系统,通过 HTTP 和协议变换提供路由和消息服务的虚拟网络。

防火墙

防火墙经常出现在大公司网络中,它几乎过滤掉了除 HTTP 外的所有东西,现在一些家庭也使用特别的防火墙,称做个人防火墙,这样称呼它是因为它运行在用户的 PC 机上。防火墙经常被配置为过滤掉除了 HTTP 外的所有东西,而 HTTP 通信只在由客户机发起时才被允许进行,因此在防火墙内的计算机和防火墙外的计算机进行通信就非常不方便,防火墙内的计算机更是无法通过 HTTP 协议主动发起与防火墙外的计算机进行连接。例如,当你请求一个网页的时候,连接到服务器,发送请求,收到请求的网页,断开连接。在任何时候都不会是 Web 服务器主动发起一个到浏览器的连接。

因为只能是单向的发起 HTTP 通信连接,网关 Peer 作为一个缓存消息的虚拟代理。因此如果一个源 Peer 想和另一个目的 Peer 交流,源 Peer 只能发起通信,网关缓存这个消息直到目的 Peer 使用 HTTP 联系同关请求获得发给它的消息,也就是目的 Peer 只能通过查询方式来获得发给它的消息。

NAT(网络地址转换)

网络地址转换是指某个内部网络中的所有计算机在进行外部访问时,通过网络地址转换使得所有的计算机只使用一个对外 IP,而当访问的内容返回内部网络时,再把内容转发给相应的发出请求的内部计算机。一个网络地址变换设备和防火墙一样具有妨碍网络通信的作用,大多数用于 cabLe 和 DSL 的宽带路由器使用网络地址变换。

NAT 使用一个单一的 IP 地址标志整个网络。因为 ISP 按照 IP 地址收费,很多人使用 NAT 节省开支。处于因特网和局域网间的 NAT 设备重写 IP 地址和端口号使得所有的数据包看上去都用的是 NAT 设备的 IP 地址,而不是真实的源或目的地址。那些需要来回通过 NAT 传递地址和端口的应用因此产生了很多问题,NAT 一般不能侦测和纠正消息以反映地址映射。实质上这意味着 NAT 内部的计算机的地址是不清楚的。

出于安全性的原因,一些 NAT 只允许那些曾经被内部访问过的外部地址(内部有数据包发往这些地址)的数据进人。这和一些个人防火墙相似,它不允许有人在你没有主动发起第一次通信前直接连接到你的计算机,这就像一部单向电话,你不能接听来电,但是可以拨打电话。

采用 NAT 可以导致一个 Socket 连接可能被分配到同一个外部地址/端口以进行随后的连接。这意味着你不可能确定消息的返回地址,这样使得建立双向会话非常困难。

网关 Peer 采用处理防火墙一样的方法处理 NAT。通过使用 HTTP 协议,同关 Peer 确保 NAT 外部的 Peer 可以与处于 NAT 内部的 Peer 通信。

代理服务器

一个代理服务器是一个处于因特网和局域网间的设备,代理服务器提供诸如过滤、缓存和流量监测等服务。使用代理服务器和使用 NAT 导致相似的结果。代理服务器可以和 NAT 一样限制地址和映射地址,它也可以像防火墙一样限制一些类型的通信。例如,一项代理服务可以防止你访问一个禁止的网站。一些代理服务器甚至可以在 E-mail 进人你的电子邮箱之前发现其中嵌入的病毒。

同关 Peer 通常可以通过 HTTP 来接人代理服务器,但是一些非常复杂的系统可以通过编程来发现并防止这种 HTTP 通信。一些公司只允许纯 HTML 通过,丢弃所有的其他类型的数据。因此在一些情况下,没有网络管理员的允许和配置你可能不能使用 JXTA 应用程序。

DHCP(动态 IP 分配)

许多公司特别是 ISP 使用动态主机配置协议(DHCP)。DHCP 动态地为计算机分配

IP 地址。结果是每一次当 DHCP 服务器或者是用户电脑重启时,IP 地址就发生了变化。IP 地址同样会因为过期而发生变化。这样导致了一个已知的地址也是暂时的地址。因为 DHCP 的存在,就算你的计算机处于防火墙之后,Peer 一样可能不会拥有可以信赖的地址。这就使得通过防火墙与另一端的 Peer 通信变得困难。

可能发生的地址变化情况因为有路由器 Peer 的存在而得到改善,当地址发生变化时路由器 Peer 能够在 Peer 间建立新的路由。

网络的不稳定

Peer 可能会消失然后又出现,这是经常发生的事情。很多计算机不是一天 24 小时都连入因特网,一些计算机还在用拨号上网并且只是在一部分时间内在线。我们还必须考虑无线设备经常只是在非常短的一段时间内上网。笔记本和 PDA 也是经常接入和离开网络。在这些情况下,同一个 Peer 甚至可能从不同的城市不同的网络拓扑中冒出来!

因为这些可能出现的变化,能够确定路由的有效性和重新路由是非常重要的。

网关问题

采用网关 Peer 可以解决上述一些问题,但是网关 Peer 本身的一个问题是它们会明显地增加消息在两个 Peer 间传送的时间。如果存在很多网关 Peer 的话,一条消息的传送时间可能会达到好几分钟。

由于消息可能需要一段很长的时间进行传输,对于用户的期望就存在一个很大的问题。这里有一个重要的参考数字 200ms,200ms 是按下一个按钮到与按下按钮相联系的事件发生的时间。换句话说,如果动作在按下按钮后的 200ms 或更短的时间内发生,那么按下按钮与反应动作仿佛是同时发生的。如果应用程序对按钮按下的反应超过 200ms,用户就要等待。用户等的时间越长,用户越可能想什么东西出错了。当用户认为应用程序没有工作,用户可能会再次单击按钮、结束应用程序重试一次或者是执行一些其他的你希望避免的操作。

当用户对应用程序有输人时有可能会进行一些 JXTA 处理,这时作为反馈应该立刻显示一些等待信号或是弹出一个等待对话框。在软件中一些包含 JXTA 网络通信的模块应该放入和用户界面不同的线程体内。此外当等待 JXTA 网络时,一些诸如等待对话框或状态显示等类型的反馈是很有必要的。应用程序可能会变得复杂一些,而且你也需要添加更多的代码使得线程安全,但是需要这些努力使你的应用更能让人接受。

Peer 和对等组

Peer 和对等组是 JXTA 中最重要的两个概念,Peer(对等机)是 JXTA 网络中的单独的节点。除了可以在一台机器上运行多个 Peer 外,Peer 与网络中的计算机相似。Peer 可能是一台 PC、一个 PDA、一台电气设备,甚至是一台超级计算机。

Peer 和用户的关系

Peer 的概念与用户的概念不是等同的。一个 Peer 是网络中的一个节点,考虑因特网中的一台普通计算机,你不能假定只一个人使用它。这台计算机可以被一个家庭分享,或者是一台公用设备。你同样不能假定一个 Peer 节点是一个用户惟一接入 P2P 网络的地方。同一个用户可以从家中、办公地点访问网络,也可以通过不同的设备接人网络。

在设计 P2P 服务和应用程序的时候,要尽量避免将用户联系到 Peer,不管是永久的或是一段时间的。有些时候你可以将用户联系到 Peer,但是要能够注销用户和登录用户。在 P2P 应用程序中有一件你需要处理的事情是身份。在许多方面 Peer 和用户相联系,因此现在我们要以 Peer 的形式来进行讨论。在多个 Peer 可能对应为同一个用户的情况下,你需要建立一套身份确认系统。

在 P2P 应用中需要确认 Peer 的权利以使其能使用服务。在 JXTA 中信任书代表了 Peer 的身份。贯穿整个系统,信任书被用来确保一些特定的操作得到了正确的许可。信任书在一个 Peer 加人到一个对等组时正式产生。信任书也可能是简单的一个提前产生的令牌并且作为 Peer 加人到对等组过程的一部分。在加人对等组的身分确认过程中,对等组认可该信任书。

对等组的必要性

网络与传统网络有几个关键的区别,其中最重要的本质是能够控制 Peer 可以做的事情。下面列出了一些问题:

*许多 Peer 连接到同一个 Peer 请求资源。

*一些 Peer 只使用资源而不提供资源。

*一些资源只能提供给部分成员。

*网络上的黑客尝试破坏或非法接管网络。

在 P2P 网络内,想要控制那些"不守规矩"Peer 的行为是非常困难的,存在许多不同类型的恶作剧行为,包括滥用其他 Peer 的资源。很明显出于安全和隐私原因,限制对应用和资源的访问是必需的。因此采用对等组管理的办法是非常必要的。

为了理解这些问题是怎样被克服的,让我们看一看一个简单化的 P2P 系统用例图,如图 3.3 所示。用户与 service-A 的不同实例交互,service-A 与其他服务协作以访问依附在特定实例上的特定资源。在这种类型的 P2P 网络中,服务要负责处理安全问题。每一个 Peer 上的每一个服务都必须控制本 Peer 的数据。

图 3.3 不分组的 Peer 访问

图 3.4 描述了 JXTA 是如何工作的。在 JXTA 中,对等组是一个虚拟的守护者。服务和服务的数据存在于对等组的范围中。对等组的代码被复制到每一个平台上,不过我们把它看做为可以被对等组中所有成员访问的一个单一的实体显示出来。服务通过对等组进行访问,并且服务是有对等组作为访问范围的。

图 3.4 分组的 Peer 访问

这里关键的区别是对等组包含了安全特性,而服务只关心 Peer 是不是合法的对等组成员。给予 Peer 的由对等组创建的信任书将在最大范围内有效。图 2.6 显示了在 JXTA 中对等组有纲领性的作用。可以看出,用户与被对等组控制的服务交互。对等组确保了只有一个控制点,不管实际的服务和数据是分布在什么地方。

通过使用对等组,至少有一个机会通过一个普通的认证方案来控制 Peer。同时就有了一个用来传播消息到一组对等组成员的平台。例如可以发送消息到其他 Peer,同时忽略无关的 Peer。

JXTA 应用程序与对等组

一般说来,JXTA 的应用程序运行后,就要作为一个 Peer 加人到一个对等组中,但是第一个对等组在哪里?JXTA 应用程序不可能通过 IP 多播在因特网上找到相应的对等组。在 Sun 公司提供的 JXTA 参考实现中,目前已经建立了一个世界范围内的对等组,参考实现中的 JXTA 的应用程序的例子都内嵌了这个对等组的地址,在运行后都自动加人到这个对等组中。World Group 是所有 Peer 都可以访问的 Group。World Group 用来定义可以被所有 Peer 访问的 Peer 或信息。在 JXTA 平台初始化以后,Peer 就成为了默认的世界对等组中的一员。从这一点来说,可以从世界对等组开始你的应用程序并使用世界对等组提供的所有默认服务。

对等组的成员资格

为了认证一个 Peer 是否属于某个对等组,在 JXTA 中专门有 Peer 成员协议(Peer Membership Protocol,简称 PMP)来确保 Peer 的成员资格。成员资格有两点关键特性------认证和信任书。认证是对等组的看门人,而信任书是确保认证发生的令牌,认证和信任书都可以复杂或简单,依赖于对对等组要求的严格性。

认证是一个对等组要求 Peer 提供加人对等组信息的多步过程。这些提供的信息随后按照对等组的成员资格需求进行有效性验证。最常见的有效性验证是用户 ID 和密码,约束不大的系统可能不要求提供任何信息或者只是一组简单问题,在约束要求最严格的系统里,认证者可能要求加密的数字签名。

信任书也可能有不同的内容。因为信任书需要被提交,它们通常相当小以减少开销。在约束性最小的对等组中,信任书只是一个简单的令牌。在对用户身份多疑的对等组中,信任书将是一个经过加密的数字签名包。

对等组的服务

对等组是用户组域内的服务进行交互操作的环境。对等组提供了一系列的服务,这些服务使用 JXTA 协议为它提供必要的功能。虽然这些服务并不是必需的,但是大多数的组都将有可能把它们提供给其他服务和应用程序使用。组是可以包含任何服务的,并且不同的组可以包含同样的服务。服务总是和组联系在一起的,如果你不是某个组的成员,你就无权访问它们。任何组所提供的服务都被列在该组的公告中。

与某个组相关联的服务的作用被局限在它们自己的范围内。通常,这些服务不会与不同组 Peer 交互,原因之一是这些 Peer 不属于同一组,还有一个特别的原因是这些 Peer 没有服务所需要的资源,所以服务没有理由与它们交互。

写一个很多组都可以操作的服务是有可能的,这样一个服务不太可能是为了访问服务。这种访问将禁止任何被标记为不属于这个组的消息,任何能被不同组使用的服务都必须有这种访问该组服务的权限。如果你需要与多个组交互,让 Peer 加人每一个组是更为简单的办法,因为每一个 Peer 加入多少个组是没有限制的。

不是所有的组都有同样的服务公告,但是所有的组都支持一系列的用于代表核心协议的标准服务。当然不包含任何这些服务或者提供完全不同的一些服务也是可能的,但是没有这些"核心服务",与其他 Peer 的交互将是很困难的。除了这些核心服务,组的创建者也可以添加额外的服务,对于这些服务没有特殊要求的。然而,这些额外服务只能在该组的范围内起作用。如果使用这些核心服务进行发现和通信交流,对组范围的限制是自然存在的。JXTA 的对等组提供的核心服务如下所示。

发现服务(Discovery Service):发现服务提供了访问组环境中的 Peer Discovery Protocol 的方法。它搜索对等组资源(Peer、对等组、管道、服务),这种搜索仅仅限于包含着发现服务引用的组范围内进行,所以如果一个组被创建并且你使用它的发现服务,只有那些组的公告才能被搜索到。然而,需要注意的是这还取决于组的操作,组可以将它的搜索扩展到它的父组、兄弟组。一些组可以从父组继承搜索范围。默认情况下,全局组可以访问所有的 Peer 公告以及在它的环境中建立的其他公告。其他组的默认行为就是仅在本组范围内搜索。

成员资格服务(Membership Service):成员资格服务提供了访问对等组成员资格协议方案的方法。在组内,成员资格被用来当作该组的守门人。Peer 想加人这个组就必须满足这个服务的要求。如果 Peer 被批准,那么这个 Peer 被认为是该组的成员并且被颁发信任书用来作为通信期间的成员资格的证明。这种成员资格能将这种模式从应用程序扩展到外部认证(像确认用户初始信任书的服务),或者查询其他 Peer 或用于最终确认的管理 Peer。

访问服务(Access Service):访问服务是成员资格服务的一部分,常被用来确认 Peer 是否确实是组的有效成员。这种服务使用那种在 Peer 加人组时创建的信任书。一个收到访问请求的 Peer 将要求发出请求的 Peer 提供信任书以及访问服务所要求的信息,并且如果环境和信任书都正确的话,访问将是允许的。

Peer 认证服务(Peer Authentication Service):这种认证服务使用被成员资格服务协议创建的信任书来确认来自组的有效成员的消息的正确性。这一概念还可以这么理解,应用程序在执行一些需要确认通信是否是在有效的 Peer 之间进行的操作时,会检查信任书。认证使用信任书作为单独信息包,信任书中的信息既可以是自认证的也可以被当前 Peer 从别的资源处获得的信息所校验。在当前的 Java JXTA 平台上还没有实现 Peer 认证服务。

管道服务(Pipe Service):管道服务实现了管道绑定协议。在不同的组之间或同一组之内,可以利用管道服务来管理和创建组中各种实体的管道连接。

解析服务(Resolver Service):解析服务实现了解析协议。解析服务可以把查询任务分发到同一组中的其他实体上,也可以监测这些查询的结果。

监测服务(Monitoring Service):一个实体利用监测服务来监测对等组中的其他组成员的行为,需要监测的内容是由实现者决定的。可以利用该服务搜集不同实体上的数据,以保证这些实体遵循组的行为规则,或是仅仅获得一些简单的统计量。这项服务在规范中已经说明了,但是很少有人实现了这些规则,因此没有相应的 API 可以利用。

如果你想实现该服务,需要把它作为你创建的组的一部分,由自己来实现。

核心服务并不需要特定的实现,但是组的核心服务能为组提供特定的行为,例如,

成员认证服务可以是一个特定的实现。核心服务除了可以被定制以外,甚至也可以不用提供。例如,假如没有监测的必要,可以不提供监测服务;假如实体已经清楚地知道对方的存在,也可以不提供发现服务。惟一的最需要提供的服务是成员认证服务,原因是当一个实体加入到一个组时,该服务被应用。假如一个组不需要提供成员资格服务,则成员资格服务的实现可以为空。

广告(Advertisement)

广告是 JXTA 的语言,P2P 网络中所有有关 Peer、对等组、服务以及其他 JXTA 构件的信息都是由广告来定义的。所谓的广告就是 P2P 网络中的名片,任何资源(包括 Peer、对等组、服务等)都要在 pP 网络中描述自己的存在和特性,并且让其他的 Peer 能够访问自己。以下列出了广告的主要类型:

  • Module Class Advertisement(MCA)------模块类广告,定义模块的具体版本。

    *Module Specification Advertisement(MSA)--模块规范广告,用跨平台的定义来描述模块,定义中包含行为。

*Module Implementation Adverti。ment(MIA)------定义某一特定平台上模块的具体实例。

复制代码
*PipeAdvertisement--管道广告,用于惟一标志管道资源的信息。

*PeetGroupAdvertisement(PGA)一对等组广告,它包含了用来实例化一个对等组时所必须的信息,包括组的服务、端点以及其他信息。

PeerAdvertlsement(PA)------Peer 广告,描述 Peer 的信息。

*EndpointAdvertisement------端点广告,定义通信协议。

实际应用中仅将广告划分为三种类型:Peer 广告、对等组广告和其他。但也并不是说这就是最好的划分,只是因为在 Java 实现的缓存机制中是用这三种类型来对广告进行分类存储的。

广告的类型

现在我们来看一下 JXTA 应用的每一种广告以及它们的含义。我们同时也做了一些 XML 示例,以便于我们了解在调试中如何认识广告。

对等组广告

对等组广告定义了对等组的标志和组的服务,它包含以下信息:

*Name------组的名称。

*Description(Desc)------对于一个对等组的描述。

*PeerGroup ID(GID)------组内每一个成员所具有的统一标号。

*PeerGroup Specifieation ID(MSID)------本组所使用的模块的标号,此标号用来确定与本组所使用的服务有关的模块。

*Service(Svc)------对等组所提供服务的列表,由它们的 Class ID(MSID 的值)和参数(通过 Parm 提供)来表示。

以下是一个对等组的 XML 格式的对等组广告的例子。

复制代码
< ?xml version = "1 .0"? >
                 < !DOCTYPE jxta: PGA >
                 < jxta: PGA xmlns: jxta = "http: //jxta .org" >
                         < GId >
                         urn: jxta:uuid-AAA122616461AAAAAAA124615032503302
                         < /GId >
                         < MSID >
                         urn: jxta: uuid-DEADBEEFDEAFBABAFEEDBABE000000010306
                         < /MSID >
                         < Name >
                         JPDA_ROOT_GROUP
                         < /Name >
                         < Desc >
                         Root application group
                         < /Desc >
                         < /jxta: PGA >

Peer 广告

Peer 广告与对等组广告大致相同,它们的主要区别就是它们的类型。

*Name------Peer 的名称。

*Description(Desc)------对 Peer 的描述。

*Peer ID(PID)------与此 Peer 实例相关的标号。

*PeerGroup ID(PID)------所属的对等组的标号。

*Debug Flag(Dbg)------用于调试的可选的标签。

*Service(Svc)------Peer 所属的组所提供服务的部分列表,由它们的 Class ID(MCID 的值)和参数(Parm 提供的参数)来表示。在大多数实现中,此部分常常包括与 Peer 交流所需的详细信息。

以下是一个 XML 格式的 Peer 广告的例子。这个例子的服务在 MCID 和 Parm 中定

义,它是 Peer 默认实现的服务。此数据包括用于 TCP 协议、组和 HTTP 网关使用的 HTTP ID 的端点。第二个 MCID 指明了安全管道的实现和验证。

复制代码
< ?xml version = "1 .0"? >
<!DOCTYPE jXta:PA>
<〕XtX:PA xmlns:jxta="http://jxta.org">
<PId>
urn:jxta:uuid5032503356CFE036E4038ABE180lD40772DC803
</PId>
<GID>
urn:jxta:jxta-NetGroup
</GID>
<Name>
</Name>
<Svc>
<MCID>
urn:jxta:uuid-DEADEEFDEAFBABABAFEEDBABE0000000805
</MCID>
<Parm>
<Addr>
tcp:198.1.0.70:9701/
</Addr>
<Addr>
jxta://uuid-59616261646162614A7874761503253356CFE036E4038ABE180lD40772DC803/TlsTransport/jXta-WorldGroup
</Addr>

<Addr>

jxta://uuid-59616261646162614A8747615032503356CFE036E4038ABE1801D40772DC803
</Addr>

<Addr>

http://JxtaHttpClientuuid-59616261646162614A7874615032503356CFE036E4038ABE1801D40772DC803
< /Addr >
< Parm >
< /Svc >
< svc >
< MCID >
urn:
jxta:
uuid-DEADBEEFDEAFBABAFEEDBABE05
</MCID >
<Parm >
<RootCert >
MIICODCCAaGgAWIBAgIBATANBgkqhkiG9w0BAQU
cuanh0YS5vcmcxCzAJBgNVBAcTALNGMQswCQYDVQQGEChzESMBAGA
lUEtwU2thbndhLUNBMR0unDVQQLExRDMKEtalDLGNDBBRjc4NKEyOUI
0RTAeFw0chTEyMj EonDIzNTLaro0XMTEyMjEunIzNTLaMGQxFTATBgN'VB
AoTDHdsny5qeHRhin9yZzE1nsca1UEBANCU0YxCzAfBgNaBAfThWTrmIw
EAYDVQQDtheLTa2FuZGEtQ0ExHTAbBgNVBAsTFEMyQTA0OULYonEFGNag2QTI
5QjRFMIGWsGCSqGSIb3DQEBAQOBiWgYcCgYEArRbPEHoij/J0PyaI/B
7xPmj1MsVX5BmrJqNUjsaEroJewrJ3ffDAyNOLWWCmTGD8maUhl,K7VycVo
aboaaaeLOJSDjKZ/gDBYgLWDrciFsMsKTswdYdP6x3/SmpDu7AVPVP
yqDUNNCMXPL+OfVflpSVZXX7MCAREwDQYJKoXIhvcNAQEFBQADgYEAGR
whIRoq0EQQEfg3jIdcMIChIpYCIAq06VLKESntqBCCnfNzAnFMeJMG
ZmZqG321wMVQytRMUr2eWnVJjvsVAiHLerd1bgUzKoIpcJy6 BdX+/Cui
FUWxkQu+GTNcjtlytjGbPNyInUxg7bPTOXU55clXDzN/+ASMLqXo8 =
    < /RootCert >
    < /Parm >
    < /Svc >
    < / jxta:
    PA >

模块(Module)广告

模块是一个 Peer 或一个组内可用的服务和应用的定义。模块用来定义被执行的代码。为了确保不同的 Peer 可以由不同的语言、版本和操作系统来完成,模块由三种不同的 XML 广告来定义:

*Module Class------定义模块的具体版本。

*Module Specification------用跨平台的定义来描述模块,定义中包含行为。

*Module Implementation--定义某一特定平台上的模块的具体实例。

上述每一种广告都是用来缩小-Peer 所使用的最终实现的范围的。但是,可能在网络上仅仅能得到各自的 ID,而得不到真正的广告。这是因为一些模块不是公共的,或者是因为它们没有不同的版本和实现。下面三部分分别讲述了广告的不同类型。

模块类广告

模块类广告用于定义行为。所有的对等组、Peer 以及其他的广告都会引用到一个由模块类广告定义的模块类 ID。模块类广告有以下三个参数:

*Module Class ID(MCID)------模块类的惟一标志符。

*Name--模块的名称,用来识别和发现,但并不惟一。

Description(Desc)一描述信息。

以下是一个模块类广告的 XML 例子。

复制代码
< ?xml version = "1.0 "? >
                 < !DOCTYPE jxta:MCA >
                 < jxta:MCA xmlns:jxta = http://jxta.org >
                         < MCID >
                         urn: jxta:uuid-2584FEB44D3B40E9Al9ABE05
                         < /MCID >
                         < Name >
                         JXTAMOD:JXTA-EX1
                         < / Name >
                         < Desc >
                         Tutorial example to use JXTA module advertisement Framework
                     < /lDesc >
                     < /jlxta:MCA >

模块规范广告

模块规范广告是一个模块的具体规范。它包含一个模块规范 ID 所指明的实现的相关信息。因为模块的代码常常是一个 Peer 应用程序的一部分,所以没必要给每个 ID 发布广告,但是通过广告发现模块却是一个很好的方法。每一个模块都包含以下标签:

*Module spec ID(MSID)------定义一个具体模块的 ID。

Compatibility statement------一个 XML 规范,用于定义代码的编写语言和版本的相容性。

Name------具体规范的规范名称。

Description(Desc)------对用于识别和发现的规范的描述。

Creator(Crtr)------规范的创建者。

Specification URI document(SURI)------规范文件的地址。

Version(Vers)------此规范的版本。

Parameters(Parm)------实现所用到的参数列表。

*Proxy------代理模块的模块规范 ID(也可能没有代理)。

Authenticator(Auth)------模块认证者的模块规范 ID。

以下是一个模块规范广告的 XML 例子。

复制代码
< ?xml version = "l.0"? >
                 < !DOCTYPE jxta:MIA >
                 < jxta:MSA xmlns:jxta = http://jxta.org >
                         < MSID >
                         urn:jxta:uuid7B181B34E6058D3DA230D2
                         ABA479BC03B06
                         < /MSID >
                         < Name >
                         JXTASPEC:JXTA-EX1
                         < /Name >
                         < Crtr >
                         sun.com
                         < /Crtr >
                         < SURI >
                         http://www.jxta.org / Exl
                         < / SURI >
                         < Vers >
                         Version 1.0
                         < /Vers >
                         < jxta: PipeAdvertisement >
                         < Id >
                         urn:jxta:uuid-9CCCDF5AD8154D3D391210404E59BE4B2241
                         Al9504
                         < /Id >
                         < Type>
                         JxtaUnicast
                         < /Type>
                         < Name >
                         JXTA--EX1
                         < / Name >
                         < / jxta: PipeAdvertisement >
                         < / jxta:MSA >

模块实现广告

模块实现广告是模块定义的最后一个环节。它定义了与 Peer 的具体语言表示相关的具体引用。此广告用于发放代码。

*Name------与模块相关的可选名称。

*Description(Desc)一一用来描述和批准用于查询模块的关键词,是一个可选项。

*ModuleSPecID(MSID)------用于识别所要实现的规范的惟一标志符。

*Compatibility(Comp)------对运行环境的描述。对于 Java 此应该是 JVM 的版本。

*Package URI(PURI)------可下载此实现的可选 URI 地址(在 JXTA 版本 1.0 中尚未实现)。

*Code------包含下载和运行此实现的相关信息。对于 Java 模块而言这是一个完全合法的类名。

*Parmeter(Parm)------由此实现代码解释的任意参数。

*提供者(Prov)------此实现的提供者。

下面是标准对等组的模块实现广告。值得注意的是,在标签 <Parm> 中包含了又一级的实现广告,并且此广告的最后一个入口是 shell 应用。这种定义方式是将 shell 作为对等组的默认应用。一旦对等组初始化完毕,标签中的应用代码就开始运行。

复制代码
< ?xml version = "1.0"? >
                 < !DOCTYPE jxta:MIA >
                 < jxta:MIAxmlns: jxta = http://jxta.org >
                         <MSID >
                         urn: jxta: uuid-DEADBEEFDEAFBABAFEEDBABE000000010306
                         < /MSID >
                         < Comp >
                         < Efmt > JDK1.4 < /Efmt >
                         < Bind >v1.0 Ref Impl< /Bind >
                         < /Comp >
                         < Code >
                         net.jxta.impl.peergroup.StdPeerGroup
                         < /Code >
                         < PURI >
                         http: //www.jxta.org/down1oad/jxta.jar
                         < /PURI >
                         < Prov > sun.com < /Prov >
                         < Desc >
                         General Purpose Peer Group Implementation
                         < /Desc >
                         < Parm >
                         < Svc >
                         < jxta:MIA >
                         < MSID >
                         urn: jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000060106
                         < /MSID >
                         < Comp >
                         < Efmt > JDK1.4 < /Efmt >
                         < Bind >Vl.0 Ref Impl< /Bind >
                         < / Comp >
                         < Code >
                         net. jxta.impl.Rendezvous.RendezVousServiceImpl
                         < /Code >
                         < PURI >
                         http: //www.jxta.org/download/jxta.jar
                         < /PURI >
                         < Prov > sun.com < /Prov >
                         < Desc >
                         Reference Implementation of the Rendezvous service
                         < / Desc >
                         < / jxta:MIA >
                         < / Svc >
                         < Svc >
                         < jxta:MIA >
                         < MSID >
                         urn: jxta:uuid-DEADBEEFDEAFBABAFEEDBABE06
                         < /MSID >
                         < Comp >
                         < Efmt > JDK1.4 < /Efmt >
                         < Bind > V1.0 Ref Impl < /Bind >
                         < /ComP >
                         < Code >
                         net.jxta.impl. discovery-DiscoveryServiceImpl
                         < / Code >
                         < PURI >
                         http: //www.jxta.org/download/jxta.jar
                         < /PURI >
                         < Prov > sun.com < / Prov >
                         < Desc >
                         Reference Implementation of the DiscoveryService service
                         < /Desc >
                         < /jxta:MIA >
                         < /Svc >
                         < Svc >
                         < jxta:MIA >
                         < MSID >
                         urn: jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000050106
                         < /MSID >
                         < Comp >
                         < Efmt > JDK1 .4 < /Efmt >
                         < Bind > V1.0 Ref Impl < /Bind >
                         < /Comp >
                         < Code >
                         net. jxta.impl.membership.NullMemberShipServiceImpl
                         < /Code >
                         < PURI >
                         http://www.jxta.org/download/jxta.jar
                         < /PURI >
                         < Prov > sun.com < /Prov >
                         < Desc >
                         Reference Implementation of the MembershipService service
                         < /Desc >
                         < /jxta:MIA >
                         < /Svc >
                         < Svc >
                         < jxta:MIA >
                         < MSID >
                         urn: jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000070106
                         < /MSID >
                         < comp >
                         < Efmt > JDK1 .4 < / Efmt >
                         < Bind >Vl.0 Ref Impl < /Bind >
                         < / Comp >
                         < Code >
                         net.jxta. impl.Peer.PeerInfoServiceImpl
                         < /Code >
                         < PURI >
                         http: //www.jxta.org/download/jxta.jar
                         < /PURI >
                         < Prov > sun.com < /Prov >
                         < Desc >
                         Reference ImPlementation of the Peerinfo service
                         < /Desc >
                         < / jxta:MIA >
                         < / Svc >
                         < Svc >
                         < jxta:MIA >
                         < MSID >
                         urn:jxta:uuid-DEADBEEFDEAFBABAFEEDBABE000000020106
                         < /MSID >
                         < Comp >
                         < Efmt > JDK1.4 < /Efmt >
                         < Bind >V1.0 Ref Impl < /Bind >
                         < / Comp >
                         < Code >
                         net.jxta.impl.resolver.ResolverServiceImpl
                         < /Code >
                         < PURI >
                         http: //www.jxta.org/download/jxta.jar
                         < / PURI >
                         < Prov > sun.com < / Prov >
                         < Desc >
                         Reference Implementation of the ResolverService service
                         < / Desc >
                         < / jxta:MIA >
                         < / svc >
                         < Svc >
                         < jxta:MIA >
                         < MSID >
                         urn: jxta:uuid-DEADBEEFDEAFBABAFEEDBABE06
                         < /MSID >
                         < Comp >
                         < Efmt > JDK1 .4 < /Efmt >
                         < Bind >V1.0 Ref Impl < /Bind >
                         < / Comp >
                         < Code >
                         net.jxta. impl.pipe.PipeServiceImpl
                         < /Code >
                         < PURI >
                         http: //www.jxta.org/download/jxta.jar
                         < / PURI >
                         < Prov > sun.com < /Prov >
                         < Desc >
                         Reference Implementation of the PipeService service
                         < /Desc >
                         < /jxta:MIA >
                         < /Svc >
                         < APP >
                         < jxta:MIA >
                         < MSID >
                         urn:jxta: uuid-DEADBEEFDEAFBA8AFEEDBABE0206
                         < /MSID >
                         < Comp >
                         < Efmt > JDK1.4 < /Efmt >
                         < Bind >V1.0 Ref Impl < /Bind >
                         < /Comp >
                         < Code >
                         net.jxta.impl. shell.bin.Shell. Shell
                         < /Code >
                         < PURI >
                         http: //www.jxta.org/download/jxta.jar
                         < /PURI >
                         < Prov > sun.com < /Prov >
                         < Desc >
                         JXTA Shell reference implementation
                         < /Desc >
                         < / jxta:MIA >
                         < /APP >
                         < /Parm>
                         < /jxta:MIA >

管道广告

管道广告描述了管道的类型。管道广告相当简单,它仅包含一个名称、一个 ID 和一个类型。正如我们已经讨论过的,管道有几种不同的类型,每个管道的具体类型在 Type 标签中指明。

管道广告包含以下标签。

.Name------管道的名称。

.Id------管道的 ID。

.Type------管道的类型,共有三种:UnicastType、UnicastsecureType 和 PropagateType。管道的类型与协议有关,因此也与 Peer 的端点相关。

下面是一个 XML 格式管道广告的例子,此管道是一个 Unicast 类型的管道。

<?XML version="l?>

<!DoCTYPE jxta:PipeAdvertisement>

复制代码
< jxta:
PipeAdVertisement xmlns:
jxta=http://jxta.org >
     < Id >
     urn:
     jxta:
     uuid4E50472050325
     Al0CF46E7B7041B3EBF5DA4404
     < /Id >
     < Type >
     JxtaUnicast
     < /Type>
     < Name >
     frodo. replyTo
     < /Name >
     < / jxta:
     PipeAdvertisement >

端点路由消息

路由协议采取询问和应答消息来发现路由线路。询问消息提供了目的地的 Peer ID,初始的 ID 为源端的 Pee ID。这个消息在 Peer 之间传输,由此实现了 Peer 端点路由协议。端点的路由询问消息的 XML 的 Schema 如下所示。

<XS:element name="EdnpointrouterQuery">

type="jxta:EndpointRouterQuery"/>

<XS:ComplexType name="EndpointrouterQuery">

<XS:element name="Credential" type="xs:anyType" mimOccurs="/>

<XS:element name="Dest" type="xs:anyType""/>

<XS:element name="cached" type="xs:string"/>

</XS :COmplexType>

路由器的应答消息包括由本路由器确定的路由线路的信息或由与其协作的路由器产生的应答消息。

实际的路由线路是一个 Peer 列表,除不需要同关的最终目的 Peer 外其他的都是网关,路由应答消息的 XML 的 Schema 如下所示。

复制代码
< xs:
element name = "EndPointRouterAnswer"
               type = "jxta:EndPointRouterAnswer"/ >
                      < xs: compleType name = "EndPointRouterAnswer" >
                              < xs:
                              element name = "Credential"type = "xs:anyType"
                                      minOccurs = "0"/ >
                                              < xs:
                                              element name = "Dest" type = "xs:anyURI"/ >
                                                      < xs:
                                                      element name = "Rout ingPeer" type = "xs:anyURI"/ >
                                                              < xs:
                                                              element name = "Rout ingPeerAdv" type = "xs:anyURI"/ >
                                                                      < xs:
                                                                      element name = "Gateway" type = "xs: complexType" / >
                                                                              < / xs:
                                                                              complexType>

消息(Message)

消息广告用于不同的消息协议以及用户定义的消息。消息有两种不同的类型:XML 类型和二进制类型。

XML 消息

XML 消息用于只支持文本的传输机制或作为一种普通的消息发送的方式。因为消息被认为是 Peer 间传送数据最常用的方式,同时二进制消息的传输效率比较高,因此二进制消息也是常用的数据传输方式。

XML 消息包含一个消息标签来封装了消息的数据。其中的每一个元素都有一个名字(name)、一个类型(mime_type)和一个可选的编码方式(encoding)。通过交换类型 mime_type 和编码方式 encoding,我们就可以在封闭的元素内使用任意的 XML 支持的有效数据类型。因为数据不是 XML,因此其中的符号"<"用字符串"&It"代替,而符号"&"用"&amp"代替。下面是一个 XML 消息的例子。

复制代码
< !DOCTYPE Message >
< Message version = "0" >
                    < Element name = "jxta: SourceAddress"
                                     mime_type= "test /plain" >
                                             tcp: //123 .456 .205 .212
                                             < /Element >
                                             < Element name = "stu f f" encoding ="base64"
                                                     mime_Type= "application/octet-stream" >
                                                             AAECAWQFBgcICQoLDA0OMREMF RYXGBKaGxWdHh8gISIjJCtwgPKissL
                                                             vxDnyMzQ1Njc4Oto7PD0+P0BQanERUZHSELKS0ANTk9QuvarmlhZWL
                                                             tcXV5fYGFiY2RLZmdoamprbGqUb3BxcAN0dXZ3eHL6e3x9fn+AgThDhIWGh4
                                                             jJiouMjY6PKJGSK5SVLpeYmZqbnJ2en6ChoqOKPaanqAnqq6ytrq+wsbKztLW
                                                             uru8vb6/WhCw8TFxsc =
                                                                     < / Element >
                                                                     < /Message >

进制消息

二进制消息是一个紧凑的包,它用来以紧凑的数据流的形式发送信息。当有两个字节长度时,先发送高位字节。所有的字符串均以两字节长度开始,后跟一 UTF8 字符串的值。该消息格式遵循 ABNF(见 IETF RFC 2234,在 httP://ief.org/rfc/rfc2234.txt)。

表 2.1 和表 2.2 定义了二进制消息的格式。

表 2.1 二进制消息的格式

|---------------|---------------------------|
| 名称 | 描述 |
| jxmg | 消息的开始 |
| version | 占一个字节。对于 1.0 的二进制格式,该值为 0 |
| Namespaces | 参见 Namespaces(名字空间) |
| element_count | 指定后面元素的个数,占两个字节 |

复制代码
JXTA Content Manage Service(CMS)

CMS 概述

最通用的 P2P 应用程序是什么?相信很多人都会想到用于文件共享的应用程序。主要原因在于,目前存在的大部分 P2P 系统,例如 Napster,Gnutella 以及 Freenet,都是为了实现文集或数据的共享。这些应用使得 P2P 技术引人注目。因此,数据共享也就成了 P2P 技术最流行的应用。虽然使用 P2P 技术的应用并不仅仅局限于文件共享,但是必须承认数据共享是发挥 P2P 架构优势的最有效的途径。

因此在 Peer 之间共享数据很有可能成为绝大部分 JXTA 应用的一个最基本的要求,所以有必要在 JXTA 中实现对这一点的支持。这就是 CMS 出现的原因。CMS 起着在 JXTA Peer 之间交换和共享数据的框架的作用。

那么究竟什么是 CMS 呢?

内容管理服务(CMS)是一个使 JXTA 应用可以在一个对等组的范围内共享和获取内容服务。这个服务使得 Peer 可以共享自己的内容以及定位和获取其他 Peer 上的内容。CMS 为本地 Peer 管理共享的内容,并且允许应用程序浏览和下载远程 Peer 的内容。

每一个被共享的内容由一个独一无二的内容 ID 以及一个内容广告来表示,其中内容广告提供了有关被共享内容的元信息,例如它的名字、长度、MIME 类型以及内容描述。CMS 也提供一个基于 JXTA 管道的协议用来在 Peer 之间传输内容。不象其他的 P2P 系统,运行 CMS 服务的 Peer 不需要使用 HTTP 协议来交换内容。

目前版本的 CMS 的功能并不是很强大。现在还没有实现一个强大的搜索机制以及优化的内容分发机制。无论如何,这个实现已经能满足绝大情况下的要求。

CMS 简单搜索

任何需要被共享的数据称为内容(Content)。每一份共享内容都有一个独一无二的内容 ID 和内容广告。内容 ID 利用内容本身的二进制数据所产生的唯一的 128 位 MD5 校验和。通过 MD5 校验和,可以很容易分辨出有两个不同的对等点(Peer)所共享的两个文件是否相同。内容广告以 XML 格式存储,用来描述内容的元信息,包括内容名称、长度、MIME 类型,内容标志符以及内容描述信息。对于简单搜索来说,CMS 的算法是向各个 Peer 发送一个查询字符串,Peer 收到这个查询字符串后,将会获取共享内容的文件名和内容描述。如果 Peer 认为这个内容符合要求,会将这个内容的广告返回给发出搜索请求的 Peer。需要注意的是,进行简单搜索只是去访问对方的 CMS,搜索本地符合要求的内容,并不需要请求 Peer 启动 CMS 服务。

JXTA CMS 简单搜索程序最重要的类是 ListContentRequest。ListContentRequest 类的主要功能是向远程 Peer 发送查询字符串,然后监听管道以获得返回的结果。结果返回时,JXTA 调用 ListContentRequest 类中的 notifyMoreResults 方法。结果返回后,调用 ListContentRequest 类里的 getResults 方法可获得所有满足条件的内容广告。

第四章 P2P 软件设计

前面我们介绍了 JXTA 的体系结构和基本组成,这里我们要利用 SUN 公司开发的 JXTA 参考实现的类库进行 JXTA 程序的设计和实现。开发过程采用 UML 建模的方法,开发平台为 Windows xp sp2,JXTA 2.2,JDK1.5,开发软件采用 JCreator 3.5LE。

需求分析

我们的目的是利用 JXTA 开发一个具有聊天功能和文件共享的 P2P 程序,使用该软件的所有用户均属于同一个组,用户发出的聊天信息组内成员都可以收到,用户共享的文件组内所有成员都能搜索到并有权下载。

从上面的需求我们可以得到如 4.1 所示的用例图:

图 4.1 用例图

类设计

通过上面的用例图,我们设计了如表 4.1 的类:

|----------------|------------------------|
| 类名 | 主要描述 |
| MyP2P | 主程序类 |
| AmuP2P | 通用 P2P 包,建立 Peer 之间的连接 |
| BaseMessage | 负责产生需要的消息 |
| OutputListener | 接口,重新定义 OutputPipe 监听器 |
| MyShare | 发布共享文件 |
| MyListRequest | 通过文件名搜索资源 |
| MyDownRequest | 下载资源 |

基于 Pipe 的通信连接都需要创建 InputPipe、绑定 InputPipe、创建 OutputPipe 才能通信,为了避免每次开发都要重复相似的代码,所以设计了这个类。该类能够加入世界对等组,并在世界对等组中加入自定义的 AmuStudio:NET 组,若找不到该组,则自动创建该组。之后所有的组内操作都在这个自定义组中进行。其类图如图 4.3 所示:

采用 AMuP2P 编程时,peer 建立连接的时序图如图 4.4 所示:

继承了 OutputPipeListener 类,主要用来获取绑定的输出管道。只有一个方法 public abstract OutputPipe getOutputPipe();。

复制代码
MyShare

初始化 CMS 服务,并发布共享文件。为了简化程序设计,采用了指定共享目录的方式,即规定所有要共享的文件都要存放在目录 MyShare 下。启动 CMS 服务后,该类自动将 MyShare 文件下的所有文件进行共享。其类图如图 4.6 所示:

图 4.6 MyShare 的类图

复制代码
MyListRequest

图 4.7 MyListRequest 的类图

复制代码
MyDownRequest

用来获得共享内容,继承了 GetContentRequest 类,覆盖了父类的 notifyDone、notifyUpdate 方法。同样的,也为该类实现了界面化,方便用户使用。其类图如图 4.8 所示:

图 4.8 MyDownRequest 的类图

各个类的关系如图 4.9 所示。

图 4.9 类关系图

发送聊天信息的时序图如图 4.10 所示:

图 4.10 发送聊天信息的时序图

接收聊天信息的时序图如图 4.11 所示:

图 4.11 接收聊天信息的时序图

搜索文件的时序图如图 4.12 所示:

图 4.12 搜索文件的时序图

下载文件的时序图如图 4.13 所示:

图 4.13 下载文件的时序图

程序运行效果

第五章 结论

转眼间,大学四年就要结束了。很自然地,一直以为很难的毕业设计开始要面对了。按学校的安排,我是分配到老师的那一组。一开始,由老师授权我们自由选题,所以我选了一个自己特别感兴趣的题目----P2P 软件的实现,心里还很庆幸。因为老实说,对于自己的编程的能力,还算小有信心的。然而,时间一天一天过去,事情并不是自己想象中那么容易。

首先碰到的难题是程序的运行环境,由于对 JXTA 各个版本的了解不足,导致程序编写后不能进行编译,提示版本错误。经过上网翻阅了大量资料后才知道,原来 JXTA 和 JDK 的版本是要互相配套的,它们并不是完全兼容的。了解情况后,JDK 保持用原来的 1.5 版本,而 JXTA 改换成 2.2 的版本,程序终于能够正常编译。

原本构思实现的功能有许多,但是在编码的过程中才发现实现这些功能并不是自己想象的那么简单,加上时间仓促,在短时间内是根本无法做到的。迫于无奈,只好简化程序,舍弃一部分功能。所以最终的程序也没有新建组,加入其它组,一对一聊天的功能。将重点转移到在一个自定义组内实行群聊和文件共享上。

在经过了几个星期的程序编写后,想测试两个 Peer 能否正常通讯,当运行一个 peer 后再运行相同代码的 Peer 时,程序后台提示异常,两个 Peer 也无法进行通讯。经过一番的测试和查阅资料,才明白在同一台计算机上要运行多个 Peer,必须设置不同的端口号,才能使它们正常通讯。

经过了多个日夜的奋斗,终于在最后关头成功将程序调试成功运行。心情也舒畅了好多。但是,由于时间的局限,因此可能在程序结构上,有些功能的实现还是没能精简代码。以后,我会继续努力,因为在浅浅的接触后,觉得 JXTA 实在是很值得研究学习的。总之,毕业设计不仅是对我大学所学的知识和学习方法积累的考验,特别是对学习方法的积累和应用,同时,也是一次宝贵的学习机会。

致谢

四年来的成长得益于海南大学各位老师的言传身教和悉心培养。能够耳濡目染老师兢兢业业的治学态度、敏锐创新的科学思维和身体力行的工作作风使我在今后的日子里受用无穷。

本毕业设计和论文是在文涛导师的悉心指导下完成的。对我提出的疑问和设计过程中需要注意的地方,老师都不厌其烦地耐心向我解释。特别是当我没信心完成设计时,老师还鼓励帮助我。老师严谨求实的治学态度、渊博的学识和令人敬服的工作热忱、敬业精神,使本人受益匪浅,谨此向我的导师致以深深的谢意和诚挚的敬意。设计过程中也得到了同学的关心和帮助,在此也向他们表示衷心的感谢。

尽管短暂的四年大学已经结束,但我将会在以后的工作中继续努力学习。

作者:肖钟杰

参考文献

ScottO, Traversat B, Gong L.JXTA 技术手册M.技桥译.清华大学出版社, 2004.

Flenner R, AbbottM, Boubez T. Java P2P 技术内幕M.人民邮电出版社,2003.

JXTA 工程主页,http://www.JXTA.org

JXTA 协议细节及白皮书;http://www.JXTA.org/white_papers.html

CMS 主页,http://cms.JXTA.org

Ken McCrary ,"The Gnutella File-Sharing Network and Java," (JavaWorld, October 52000),http://www.javaworld.com/javaworld/jw-10-2000/jw-1006-fileshare.html

陈烨、张蓓等,《JDK 1.5 类库大全》,清华大学出版社,2005 年

耿祥义,《Java 大学实用教程》,电子工业出版社,2005 年

许斌,《JXTA-Java P2P 网络编程技术》,清华大学出版社,2003 年

把 P2P 进行到底:讲述 JXTA 的故事,http://www.bitscn.com/java/JXTA/200605/21548.html

JXTA 技术与应用发展,http://www.bitscn.com/java/JXTA/200605/21551.html

基于 JXTA 的 P2P 应用开发,http://www.bitscn.com/java/JXTA/200605/21557.html

JXTA 技术与应用发展,http://www.bitscn.com/java/JXTA/200605/21551.html