这些阻碍将随着 Windows Vista? 和附带的 .NET Framework 3.0 版本的发布而明显改善。在将 Windows Vista 的增强功能与“对等名称解析协议”(PNRP)、People Near Me (PNM) 和 Windows? Communication Foundation 中引进的 PeerChannel 功能相结合的情况下,我们又向 P2P 应用程序跨进了一大步。我个人期望在发布 Windows Vista 之后,P2P 的舞台会更加绚丽多彩。
Windows Vista 中的 P2P 开发是一个极其广泛的主题,没有任何一篇文章可以将其阐述完整。因此,我不会去尝试完成这样一个不可能的任务,而是会介绍 Windows Vista 中一些不同的 P2P 技术,并为您对 P2P 开发工作提供背景资料。
除了假定您已基本了解 Windows 窗体之外,我还假设您已略微熟悉 Windows Communication Foundation 应用程序的编写。假如情况并非如此,您可能希望通过阅读 Windows SDK 或 wcf.netfx3.com/content/resources.aspx 中的部分内容开始起步。
P2P 基本原理:网格网络
在深入探讨具体的 P2P 技术之前,研究 P2P 应用程序的一些基本原理很重要。对初学者而言,P2P 应用程序是一个与该应用程序的其他实例直接相连的应用程序。在 P2P 语言中,该应用程序的每个实例都叫做一个节点。通常将这些节点连接和命名后的组合称为网格。因此,推动 P2P 应用程序开发的技术经常被称作网格技术。PNRP、PeerChannel(在 Windows Communication Foundation 中)和 PNM 都是 Windows Vista 中网格技术的例子。
网格技术 所有 Windows Vista 网格技术所生成的网格在拓扑结构上都大致相同。通常来讲,网格拓扑是网格中各节点间连接模式的抽象体现。为了解释清楚,请在脑海中设想一个网格。我敢断定,您所设想的网格在某种程度上与图 1 中所示的网格相似。
图 1 全连接网格
图 1 所示网格中四个节点中的每个节点都与网格中的其他所有节点相连。换言之,假如网格中有 N 个节点,则每个节点都保持 N-1 个连接。我们将达到此标准的网格视为全连接网格。全连接网格很少被用作适合的方法;要了解原因,让我们注重一下各节点间的连接。
网格中的节点基本上都使用现有的常用传输方式进行通信。与所有的现代操作系统一样,Windows Vista 利用 TCP/ip 和 UDP 进行网络通信。假如 TCP/IP 是全连接网格所选的传输方式,那么由 N 个节点组成的全连接网格中的每个节点都必须创建或接收 N-1 个套接字。随着 N 值的增加,此模型显然变得不可行。例如,假如假定一个 N=1000 的情况,那么每个节点都将需要保持 999 个套接字,这简直就行不通。
要解决可伸缩性和 WAN 连接性的问题,您必须诉诸于部分连接的网格,如图 2 中所示。顾名思义,部分连接网格中的节点只与网格中的其他少量节点相连。就 P2P 来说,这些相邻的节点被称作邻居。通常来说,部分连接网格对每个节点的资源需求更少,从而大幅提高了网格的可伸缩性。从理论上讲,部分连接网格的规模可以扩大到包括全球所有计算机上的所有应用程序。
顾名思义,PNRP 旨在基于网格名等要素来解析物理地址。PNRP 可供带有 Advanced Networking Pack 的 Windows xp Service Pack 1 (SP1) 以及 Windows XP SP2 和 Windows XP PRofessional x64 Edition 使用。Windows Vista 也将附带 PNRP 版本 2。从最简单的层次看,PNRP 本身就是一个采用 Windows 服务形式的 P2P 应用程序,并且 PNRP 节点的网格专用于发现加入到其他网格中的节点的物理地址。(有关此方面的具体信息,请参见提要栏中的“在 Windows XP 上安装 PNRP”。)
Windows Communication Foundation 的主要优点之一就是,它为许多不同类型的分布式应用程序提供了一个通用的编程模型。例如,编写一个基于 TCP/IP 通过二进制编码消息进行通信的分布式应用程序所需的代码与编写一个基于 HTTP 通过符合 WS-* 的可互操作的消息进行通信的分布式应用程序所需的代码惊人地相似。Windows Communication Foundation 的一个鲜为人知的功能就是它支持使用这同一个通用编程模型来构建 P2P 应用程序。由于 Windows Communication Foundation 对 P2P 应用程序的支持,可能会有人将其视为一种网格技术,但实际上,只有 PeerChannel Windows Communication Foundation 模块才专用于构建 P2P 应用程序。因此,PeerChannel 这个术语通常用于指代 Windows Communication Foundation 的 P2P 功能。无论 Windows Communication Foundation 中的 PeerChannel 指代的是什么,它实际上消除了通常与 P2P 应用程序开发相伴的所有复杂性,并且在我看来,它是 P2P 应用程序开发领域的一个创新性突破。
如前所述,PeerChannel 节点还可以将消息发送给网格中节点的子集。这可以通过向消息分配一个跳跃计数来实现,这实际上是跟踪转发消息所经由的节点数的方式。不要将这种机制与定向消息传送相混淆,定向消息传送是将消息传送目标锁定在某个特定节点。更确切地说,跳跃计数是模糊界定接收消息的节点数的方式。例如,假如一个 PeerChannel 节点(节点 A)有三个邻居且在跳跃计数为 1 的情况下向网格发送一个消息,则该消息将被传送到三个节点。同样,假如节点 A 的每个邻居也都有三个唯一邻居且节点 A 在跳跃计数为 2 的情况下向网格发送一个消息,则该消息将被传送到九个节点。但假如节点 A 的任一邻居有共用的邻居,则此数字将相应减少。 QQread.com 推出各大专业服务器评测 Linux服务器的安全性能 SUN服务器 HP服务器 DELL服务器 IBM服务器 联想服务器 浪潮服务器 曙光服务器 同方服务器 华硕服务器 宝德服务器 从物理上说,跳跃计数在消息中被表示为标头块中的一个整数。当某节点收到带有跳跃计数的消息时,它会检查跳跃计数的值。假如该值大于零,节点会单调递减此跳跃计数,然后将带有递减后的跳跃计数值的消息转发给相应邻居。假如所接收消息中包含的跳跃计数为 0,则不转发该消息。另需注重的重要一点是,跳跃计数标头块被排除在消息签名之外,因此更改这个值不会影响到应用于消息的数字签名的完整性,而且会防止产生与重复生成数字签名并将其序列化到消息相应部分中所关联的开销。
PeerChannel 示例 让我们用 PeerChannel 和 Windows 窗体来构建一个简单的 P2P 应用程序,称之为 PictureViewer。顾名思义,该应用程序的用途是答应网格中的所有节点可以查看同一张图片。从高层次来说,构建此应用程序所需的步骤如下所示:
1.定义基本的 Windows 窗体样板代码。
2.向窗体添加控件。
3.定义必需的 Windows Communication Foundation 服务合约。
4.编写连接到网格和从网格接收消息所需的 Windows Communication Foundation 代码。
5.编写向网格中其他节点发送消息所需的代码。
图 3 显示了完成后的应用程序。步骤 1 和 2 是开发任何 Windows 窗体应用程序时所必需的步骤,因此我将不在这里对其说明。对于任何 Windows Communication Foundation 应用程序,开发过程的第一步是定义服务合约。PeerChannel 要使用的服务合约类似于其他 Windows Communication Foundation 合约,只不过 PeerChannel 需要所有的 OperationContractAttribute 批注都将 IsOneWay 实例属性设置为 true。此属性规定消息的接收方不应发送回复。假如想要接收方发送回复,可以将服务合约定义为双向合约,但每个 OperationContractAttribute 批注仍必须将 IsOneWay 实例属性设置为 true。就此例而言,我不会创建一个双向合约(Windows SDK 中有几个双向合约的示例)。我要使用的合约如下所示:
在定义了我们的服务合约后,现在就该添加 Windows Communication Foundation 代码,该代码会将我们的应用程序连接到 PeerChannel 网格并且被动等待来自网格的消息。首先,在窗体中实现新定义的服务合约。然后,定义类型 ServiceHost 的字段。所接收的消息将被发送到 frmPictureViewer 类型的单个实例。要表明此功能,我必须将正确的 ServiceBehavior 分配给 frmPictureViewer 类型。这两个步骤如图 4所示。
接下来,我必须对 ServiceHost 进行实例化,添加端点并开始侦听外来的消息。由于我正在构建 Windows 窗体应用程序,因此实现此操作的逻辑位置就是窗体的构造函数,如图 5 所示。
此时,我已经完成了要连接到网格并侦听消息所需的所有步骤。与标准的 Windows Communication Foundation 代码相比,不同之处只在于 Uri 的方案 (net.p2p)、所使用的绑定 (NetPeerTcpBinding) 以及所增添的基于密码的安全性。请注重,我已选择将网格密码直接置于代码中,这一点很重要。假如想要使网格密码保密,请不要在您当前所使用的应用程序中如此操作。
要将包含图片的消息发送到网格中的其他节点,我必须编写几行代码,但是此代码与您在其他任何 Windows Communication Foundation 应用程序中编写的代码几乎相同。起初,我需要在类型 ChannelFactory 和 IPictureViewer 的窗体中定义一些字段。接下来,我需要在窗体的构造函数中将这些变量实例化。这些步骤如图 6 所示。
请注重,所使用的网格密码和证书(用于创建消息的数字签名)与设置 ServiceHost 时所用的必须是同一个。除此之外,此代码要与非 PeerChannel Windows Communication Foundation 应用程序中所需的代码相同。
PNM 是集成在 Windows Vista 之中的一种网格技术,它答应邻近的设备组和人员组相互发现、连接、邀请并进行协作。PNM 非凡适用于这样一些任务:在咖啡店与邻座其他几个人一起玩游戏;与同事共享您的桌面;甚至连接到会议室中的投影仪,等等。PNM 提供的这些功能如此强大,我们有理由假设,一旦它被发布,开发人员社区就将会找到新的、具有独创性的方式来利用此技术。重要的是,要注重 PNM 是一项完全自选的网格技术,在默认情况下是关闭状态。
除其他应用程序之外,PNM 体系结构包含了一个称为 p2phost.exe 的 P2P 应用程序。此进程运行时,将通过连接到其他计算机上 p2phost.exe 的实例来创建网格。通常而言,此网格的用途是定向消息传送。更确切地说,PNM 用于解析本地节点并与这些本地节点的子集进行通信。PNM API 作为 Windows API 的一部分提供,并且多半程度上侧重于配置 p2phost.exe 的行为。
总的来说,PNM API 的主要类别包括函数、结构、事件和错误代码,通过这些类别可以向 PNM 注册应用程序、邀请其他人加入协作会话、启动已注册的应用程序、创建持久性合约并邀请不再属于本地的联系人。提要栏中的“真实环境中 People Near Me 的示例”将例示此过程。请注重,不支持应用程序使用 PNM 进行通信。就 PictureViewer 而言,这表示在提要栏中说明的 Tom 和 Harry 的 PictureViewer 实例之间传递的消息仍由 PeerChannel 来处理。
结束语
P2P 应用程序开发是一个涉及范围非常广泛的主题,并且对于多数开发人员而言还相当生疏。随着 Windows Vista 和 .NET Framework 3.0 的发布,P2P 应用程序的传统开发门槛将明显降低。我相信,技术的进步(如 PNRP、IPv6)加上更具生产力的新型平台的问世(如 PeerChannel 和 PNM)将在 P2P 应用程序开发领域开创一个新时代。最终,应用程序将更具协作性,并提供我们起初只能想像的一些功能。