Peer to Peer Networking with .NET Framework 3.5
Posted by: Valer BOCAN in Visual Studio (6,853 Views)An exciting addition to .NET Framework 3.5 is the System.Net.PeerToPeer namespace, located in the System.Net.dll assembly. The new namespace provides the core building blocks for creating peer to peer (P2P) applications in .NET.
Typically, a P2P communication has three phases:
- Discovery: the process of dynamically locating peers and their associated network locations.
- Connection: establishing a network connection between peers.
- Communication: the process of passing data back and forth among peers.
The features of the System.Net.PeerToPeer namespace facilitate the discovery and connection of the peers. Communication must be performed using complementary techniques such as Sockets, HTTPWebRequest and WCF Peer Channel. The underlying technology is the Peer Name Resolution Protocol (PNRP) and it enables discovery and makes communication among peers possible by enabling serverless name resolution of any resource to a set of network endpoints. PNRP is responsible for two core tasks: publishing a PeerName for others to resolve and resolving a PeerName that was published by another peer and retrieving the associated metadata. Information about the PNRP protocol can be found on Microsoft’s website at www.microsoft.com/p2p.
Creating a Peer Name
The name of the peer can be created and registered and two ways: secured and unsecured. Secured names rely on public key cryptography and they cannot be spoofed after registration with PNRP.
PeerName p = new PeerName(“My PeerName”, PeerNameType.Secured);
or
PeerName p = new PeerName(“My PeerName”, PeerNameType.UnSecured);
Associating Metadata
The peer name can be have associated metadata, such as an IP address, a free-text comment and a binary blob. Metadata is handled by the PeerNameRegistration object.
PeerNameRegistration pnReg = new PeerNameRegistration();
pnReg.PeerName = new PeerName(“My PeerName”, PeerNameType.Secured);
pnReg.EndPointCollection.Add(new IPEndPoint(IPAddress.Parse(“<Insert an IP address to associate with the name>”), 8080));
pnReg.Comment = “<Insert up to 39 unicode char comment>”;
pnReg.Data = System.Text.Encoding.UTF8.GetBytes(“Up to 4KB associated with the name”);
If we want all local addresses to be registered with the peer name, we could use the PeerNameRegistration.UseAutoEndPointSelection and set it to true, instead of adding end points manually.
Clouds
In the PNRP context, a cloud is simply a set of computers and defines the scope to which names are published to or resolved from. When publishing a name, we need to determine which cloud (or scope) we want to publish the name to.
The current implementation of the PNRP protocol uses two clouds:
- Link-local: only other peers on the same link can resolve the name.
- Global: anyone on the Internet to resolve the name.
Publishing a Peer Name
Now that we’ve seen how to create a peer name and associate the relevant metadata, it’s time for us to publish the name with the PNRP. The code snippet below shows how it’s done:
PeerNameRegistration pnReg = new PeerNameRegistration();
pnReg.PeerName = new PeerName(“MyPeerName”, PeerNameType.Secured);
pnReg.Port = 8080;
pnReg.UseAutoEndPointSelection = true;
// Starting the registration means the name is published for other peers to resolve.
pnReg.Start();
Resolving Peer Names
Peer names registered with the PNRP can be resolved using the PeerNameResolver object. The resolving party must know the name in the first place, and then it can retrieve the associated metadata such as comments and IP endpoints. The PeerNameResolver object can be used in both synchronous and asynchronous scenarios.
PeerNameResolver resolver = new PeerNameResolver();
PeerNameRecordCollection collection = resolver.Resolve(new PeerName(“MyPeerName”, PeerNameType.Secured));
foreach (PeerNameRecord record in collection)
{
if (record.Comment != null)
{
Console.WriteLine(record.Comment);
}
if (record.Data != null)
{
Console.WriteLine(System.Text.Encoding.ASCII.GetString(record.Data));
}
foreach (IPEndPoint endpoint in record.EndPointCollection)
{
Console.WriteLine(“Endpoint: “ + endpoint.ToString());
}
}
In order to resolve several peer names at once, the asynchronous scenario can be used such that the call to PeerNameResolver does not block.
Sample Code
I wrote a small application that demonstrates how to asynchronously resolve peer names. You need .NET Framework 3.5 on your machine and your machine should run Windows Vista, Windows Server 2008 or Windows XP SP2. The sample code was compiled using Visual Studio 2008 Beta 2.




Entries (RSS)