65.9K
CodeProject 正在变化。 阅读更多。
Home

Peer Graph - 交换私有数据

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.23/5 (3投票s)

2005年12月12日

4分钟阅读

viewsIcon

86095

downloadIcon

390

使用 Microsoft 的 Peer-to-Peer 技术在对等图(peer graph)中交换私有数据。

背景

Microsoft 的 Peer-to-Peer Graphing 技术为 Windows 对等应用程序提供了稳定、可靠且健壮的基础设施进行通信。对等节点使用 Peer Name Resolution Protocol (PNRP - 一个无服务器的 DNS) 在图中注册和发现其他对等节点。图是连接对等节点、服务和资源的对等网络的基础。对等节点可以是用户交互式应用程序、服务或资源。Graphing 允许数据在对等节点之间高效且可靠地传递。

Microsoft 的整个点对点技术通过最新的平台 SDK 以 C/C++ API 调用形式公开。但是,本文中的代码展示了如何使用 C# 从 .NET 托管代码调用这些 API。

引言

本文介绍了在对等图中交换私有数据的概念。这是上一篇文章的延续,上一篇文章展示了对等节点如何使用 Microsoft 的 Peer-to-Peer Graphing 技术打开和关闭私有连接。一旦对等节点之间建立连接,任何一方都可以通过该连接发送和接收数据。PeerOpenConnection 类提供了另外两个用于发送数据的方法和一个用于接收数据的方法。

发送数据

要发送数据,示例 PeerGraph 类提供了以下 internal 函数来发送字节数组。

internal void SendData(System.Int64 ConnectionId, 
                       Guid Type, int Length, IntPtr Data)
{
  IntPtr typeptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
  Marshal.StructureToPtr(Type, typeptr, false);

  uint hr = PeerGraphNative.PeerGraphSendData(hGraph, 
            ConnectionId, typeptr, (uint)Length, Data);
  if (hr != 0) throw new PeerGraphException(hr);
}

SendData 方法调用底层的 PeerGraphSendData API。连接 ID、消息类型、缓冲区长度和缓冲区作为参数传递。此方法在数据进入网络后立即返回,不等待确认。

示例 PeerOpenConnection 类实现了两个包装函数来简化数据发送。第一个方法允许发送字符串。

public void SendData(Guid Type, string Message)
{
  IntPtr dataptr = Marshal.StringToHGlobalUni(Message);
  int size = (Message.Length+1)*2;
  graph.SendData(connectionId, Type, size, dataptr);
}

第二个方法提供了一个更通用的数据流来发送。MemoryStream 是在对等节点之间交换结构化数据的理想方式。这还允许传递文件流来发送文件的内容。

public void SendData(Guid Type, System.IO.Stream Data)
{
  int size = (int)Data.Length;
  byte[] data = new byte[size];
  Data.Read(data, 0, size);
  IntPtr dataptr = Marshal.AllocHGlobal(size);
  Marshal.StructureToPtr(data, dataptr, false);
  graph.SendData(connectionId, Type, size, dataptr);
}

在这两种情况下,都可以处理将托管数据封送到非托管指针的繁琐细节。

您可能已经注意到 SendData 方法接受一个 Type 参数。这个 GUID 值允许每种类型的消息都被唯一标识。这与 Windows 应用程序使用 WM_XXX 代码来标识消息相同。

数据接收事件

PeerGraph 类按照从另一个对等节点接收私有数据消息的顺序处理 PEER_GRAPH_EVENT_INCOMING_DATA 通知。

private void HandleEventIncomingData(IntPtr evptr)
{
  PEER_EVENT_INCOMING_DATA ndata = (PEER_EVENT_INCOMING_DATA)
                                   Marshal.PtrToStructure(evptr, 
                                   typeof(PEER_EVENT_INCOMING_DATA));

  PeerOpenConnection cn = (PeerOpenConnection)OpenConnections[ndata.ullConnectionId];
  if (cn != null)
  {
    PeerGraphDataReceiveEventArgs args = new 
               PeerGraphDataReceiveEventArgs(cn, ndata.type, 
               ndata.data.pbData, ndata.data.cbData);
    cn.RaiseDataReceivedEvent(args);
  }
}

在内部,PeerGraph 类维护一个哈希表,将所有连接 ID 映射到已打开的连接。快速查找允许传入通知在相应的、已打开的连接上触发 DataRecieved 事件。在这种情况下,RaiseDataReceivedEvent 函数处理此问题。

使用示例应用程序

示例应用程序首先允许您创建一个图(未加密的对等节点名称 0.TestGraph)并带有初始身份。第一个实例应该使用此身份打开。它将暂停几秒钟以查找其他实例,然后开始侦听。随后的每个应用程序实例都应该使用不同的身份打开图。这些实例将连接到最近的对等节点并进行同步。应用程序的每个实例都是一个对等节点。

左侧列表显示了所有操作和传入事件的诊断日志。双击以清除列表。

右侧列表显示了连接到图的所有对等节点的身份。双击一个对等节点以发起发送消息。会出现一个输入框,供您输入一些文本。关闭此窗口时,文本将发送到相应的对等节点。

private Guid WHISPER_MESSAGE_TYPE = 
         new Guid(0x4D5B2F11, 0x6522, 0x433B, 0x84, 
                  0xEF, 0xA2, 0x98, 0xE6, 0x7, 0xBB, 0xBB);

private void OnConnectionOpened(object sender, 
               PeerGraphConnectionOpenedEventArgs e)
{
  if (e.OpenConnection.ConnectionId == connectionId)
  {
    // send the data
    e.OpenConnection.SendData(WHISPER_MESSAGE_TYPE, Message);
  }
  else // receiver opened, so bind for event
    e.OpenConnection.DataReceived += new 
         PeerOpenConnection.DataReceivedHandler(OnDataReceived);
}

示例应用程序的 OnConnectionOpened 事件将连接 ID 与打开连接后返回的 ID 进行比较。匹配的 ID 表明打开连接并即将发送数据的对等节点。否则,它是接收数据的对等节点,因此它会绑定到 DataReceived 事件。

public void OnDataReceived(object sender, 
               PeerGraphDataReceiveEventArgs e)
{
  // read message then close
  LogMessage(e.OpenConnection.Connection.PeerName, e.DataAsString);
  e.OpenConnection.Close();
}

示例应用程序的 DataRecieved 事件处理程序只是将收到的消息添加到诊断列表中并关闭连接。

关注点

示例应用程序展示了一种对等节点交换私有数据的非常简单的方法。然而,这是更完整的即时通讯风格应用程序的基础。也可以使用此技术在对等节点之间交换文件。

资源链接

我发现以下资源对于理解对等图形非常有帮助

结论

希望您觉得本文很有用。下一篇文章将重点介绍与图中的所有对等节点共享数据。敬请关注以下主题的更多文章

  1. 对等名称解析 - Windows Vista 增强功能
  1. 对等图形 - 记录
  2. 对等图形 - 属性
  3. 对等图形 - 搜索
  1. 对等组和身份
  1. 对等协作 - 附近的人
  2. 对等协作 - 端点
  3. 对等协作 - 能力
  4. 对等协作 - 在线状态
  5. 对等协作 - 邀请

如果您对其他主题有建议,请留言。

历史

初始版本。

© . All rights reserved.