Anda di halaman 1dari 32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Peer-to-Peer Programming with WCF and .NET Framework 3.5


30 out of 50 rated this helpful - Rate this topic Amit Bahree (Avanade UK, www.desigeek.com) Chris Peiris (Avanade Australia, www.chrispeiris.com) February 2008 Applies to: Microsoft .NET Framework 3.5 Windows Vista Microsoft Visual Studio 2008 Summary: This article explores peer-to-peer (P2P) concepts and how they are supported in Microsoft .NET Framework 3.5. It aims to provide an understanding of P2P fundamentals, as well as show how to use the new features of Windows Communication Foundation (WCF). Finally, it introduces the new features of managing P2P networks, including the use of People Near Me and Windows Address Booknew features released as part of Windows Vista. (39 pages)

Contents
Introduction What Is New in .NET Framework 3.5? What Is Peer-to-Peer (P2P) Computing? QuickReturnTraderChat Application P2P Security QuickReturnSecureTraderChat Sample Peer Name People Near Me and Contacts Working with NetShell Debugging Tips Bringing It All Together Conclusion References

Introduction
Although the term peer-to-peer (P2P) computing has gained popularity recently, the usefulness of P2P to address business and technical problems remains poorly understood. In this article, we explore P2P concepts and how they are supported in Microsoft .NET Framework 3.5. We will also build a sample application to demonstrate the concepts that are involved. Because many of the new features of P2P in .NET Framework 3.5 are available only on Windows Vista, most of the elements that we discuss in this article require Windows Vista. You can run only a handful of things on Microsoft Windows XP; these things are discussed in the Debugging Tips section.

What Is New in .NET Framework 3.5?


Peer channel (see the What Is Peer Channel? section) was originally released as part of .NET Framework 3.0. This was a significant step for the ability to write P2P applications in managed code. However, there were many basic elements still lacking within the managed stack. The
msdn.microsoft.com/en-us/library/cc297274.aspx 1/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

only way to get around these basic elements was via the unmanaged C++ stack. .NET Framework 3.5 adds a couple of new namespacesSystem.Net.PeerToPeer and System.Net.PeerToPeer.Collaborationthat significantly improve on the availability of these basic elements via the managed stack. These new namespaces are part of the System.Net.dll assembly and are designed with the P2P application flow (described earlier) and collaboration in mind. Also, they provide access to the P2P networking infrastructure with options to find a P2P, join a mesh, start interaction, and so on. For the first time, a developer can write complete P2P applications that are developed in managed code without having to get into the unmanaged stack in C++. On the collaboration front, the System.Net.PeerToPeer.Collaboration namespace, which is also new in .NET Framework 3.5, provides two contexts for collaborating: People Near Me (see the P2P Application Flow section) and Contacts. People Near Me (PNM) is a new feature that allows applications to discover people on the local subnet and interact with them. The Contacts feature, which is also new, essentially refers to people who are trusted users and have been added as contacts. Unlike PNM, these contacts do not have to be on the same subnet for you to be able to interact with them.

What Is Peer-to-Peer (P2P) Computing?


P2P computing is a term that has gained a lot of popularity in recent times. Today, organizations and businesses increasingly depend on collaboration between individuals and groups to perform essential tasks. P2P applications form more ad hoc online groups for business, entertainment, and cultural purposes. As a result, collaboration has become more essential at an individual level. Essentially, P2P computing is a set of networked computers that rely on the computing power and bandwidth of the individual computers on the network, as opposed to the traditional approach of relying on a smaller number of more powerful server computers on the network. A computer that is connected to a P2P network can be categorized as a node or peer. The nodes in a P2P network are usually connected on an ad hoc basis. This is where the real power in a P2P network lies, because the peers are responsible for uploading and downloading data among themselves without the need for a server. Two types of P2P network exist: a pure network and a hybrid network. A pure P2P network has no concept of a client or a server; it has only nodes, which act in the capacity of both a server and a client, as needed. A hybrid P2P network, on the other hand, has a central server that keeps track of the various peers on the network. This server responds to requests from the peers for information only and does not store any data. The peers are responsible for hosting the information. For example, in a file-sharing P2P application, the files are stored by the peer, and the server is aware of the files that are stored at each peer. Most P2P solutions rely on some nonpeer elements in the solution, such as Domain-Name System (DNS, used to translate computer host names to IP addresses). Some P2P solutions also have the notion of a superpeer, in which other peers are connected to this superpeer in a star-like fashion. Over time, these superpeers could also be used as local servers.

How Are Nodes Identified?


The networks in P2P applications are also called meshes (or, sometimes, a mesh network), in that they are akin to a wire mesh. Each node in a mesh at a minimum has bidirectional communication capability with its neighbors. A cloud is a mesh network that has a specific address scope. These scopes are closely related to IPv6 scopes; the peers in a cloud are those that can communicate within the same IPv6 scope. On a mesh, each node must be identified by a unique ID that is usually called a peer ID or mesh ID. To resolve these peer IDs to their corresponding Internet addresses, the Peer Name Resolution Protocol (PNRP) is used, instead of DNS. Each peer node, irrespective of type (such as computer, user, group, device, service, and so on), can have its own peer ID. This list of IDs is distributed among the peers by using a multilevel cache and referral system that allows name resolution to scale to billions of IDs, while requiring minimal resources on each node. An endpoint is defined as a combination of a peer ID, port number, and communication protocol. By using an endpoint, a peer can send data between nodes in two ways. One way is
msdn.microsoft.com/en-us/library/cc297274.aspx 2/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

for a peer to send the data to another peer directly. The other way is for a peer to send the data to all of the other peers on the same mesh, which is also known as flooding. A flooded message could arrive at the same peer multiple times via different routes on the mesh.

Peer Names
Peer names can be registered as either secured or unsecured. Unsecured names are recommended for use in a private network only, because the names are strings and can easily be spoofed. Secured names, on the other hand, must be registered, and they are protected with a certificate and digital signature. A PNRP ID is 256 bits long; the high-order 128 bits are a hash of the peer name that is assigned to the endpoint, and the lower 128 bits of the PNRP ID are an automatically generated number that is used for service location. The format for the peer name is Authority.Classifier. When using a secured network, the Authority is a secure hash (using Secure Hash Algorithm, or SHA1) of the public key of the peer name in hex. When using an unsecured network, the Authority is the single character 0 (zero). The Classifier is a Unicode string that is up to 150 characters long and identifies the application. The autogenerated number, which is used by the lower 128 bits, uniquely identifies different instances by using the classifier that participates in the same mesh. The combination of 256-bit mesh ID and the service location allow multiple PNRP IDs to be registered from a single computer.

Name Resolution with PNRP


When one peer wants to resolve the name of another peer, it constructs the peer ID (as discussed earlier) and tries to find that entry in its cache for the ID. If a match is found, it sends a PNRP request message to the peer and waits for a response. This approach ensures that the target peer node, with which another peer is trying to communicate, is active in the cloud. If no match is found, an iterative process is used with the target peer that informs the sender of the peer that is the closest match to the ID that is trying to be resolved. At this stage, it is up to the original sender to send the same request to the matching peer as the one to which it was pointing. If the new peer to whom the sender was pointed is also incorrect, that in turn will return the next-closest matching peer to the sender, and so on. When a PNRP request message is forwarded, the nodes that are forwarded to and the responses that are received are both cached. This prevents a situation in which things could get into an endless loop.

P2P Application Flow


There are three types of P2P application: one-to-one, one-to-many, and many-to-many. When one peer in a mesh wants to communicate with another, it must find the other peer, send an invitation, and create a session between the two. These steps are described as follows: Find peerEssentially, to talk to another peer, you must first find it. There are two ways to go about this. The first is to find other peers on the LAN of which you are part. The second is to find peer or peer groups using by PNRP. If you are finding other peers on the LAN, you should use the PNM feature and integrate that into your application. PNM uses WS-Discovery to find users who are signed in. There are many requirements for this to work, such as people discovery, application discovery, metadata discovery, security, invitation, and so on. We discuss PNM in more detail later in this article. When using PNRP, on the other hand, it is a server-less name resolution that can be either on the local network or over the Internet. Send invitationInvitations are real-time and can go to PNM or peers over the Internet, via either a user message or application data such as mesh name, endpoint, and so on. A listener at the other end detects this incoming invitation request and launches the appropriate application. Join meshThe last step to establish a session is to specify the mesh name and credentials (if applicable) that one is intending to join.

What Is Peer Channel?


msdn.microsoft.com/en-us/library/cc297274.aspx 3/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Until fairly recently, the P2P networking stack was mostly available only as unmanaged code, and a developer had to use C++ to be able to use any of it. This stack is part of Windows XP, and it has been improved as part of Windows Vista and Microsoft Windows Server 2008. Microsoft also has a managed code implementation for a subset of the functionality that is exposed by the P2P networking stackcalled peer channeland is released as part of WCF. Because peer channel is a managed stack, you can use any .NET languagemaking implementation of P2P applications easier and more productive, when compared to unmanaged code. A typical WCF channel has two participantsnamely, a client and a server. A peer channel, on the other hand, can have any number of participants. A message that is sent by one participant will be received by all other participants on the channel. However, certain mechanisms in the peer channel allow you to send a message to only part of the mesh, instead of the whole mesh. To resolve the addresses of a node in a peer-channel mesh, you can use either PNRP or a custom resolver. When a node is resolved, that target node can either accept or decline the connection. If the connection is accepted by the target node, it sends it a welcome message that will contain, among other things, the list of other nodes that are part of the mesh. If the connection is refused, the existing node sends the prospective node a refusal message that contains the reason for the refusal and a list of the addresses of the other nodes in the mesh. In WCF, a node that will be part of a mesh is defined via the PeerNode class in your application. The endpoint address for that node is defined via the PeerNodeAddress class (which internally implements the EndpointAddress class). The number of neighbors of each node dictates the overall structure of a peer-channel mesh that is actively maintained, which results in an evenly distributed mesh. For example, a node in the mesh tries to maintain between two to seven connections to its neighbors. Although an ideal state for the node is to have three connections, it will accept up to seven connections. As soon as a node has reached that threshold, it will start refusing any new connections. If a node loses all of its neighbors, it will enter a maintenance cycle in which it tries to acquire new neighbors to get to its optimum state of three connections. Note that you cannot change or configure either the thresholds or the underlying mesh, because the peer channel owns and maintains this. The peer channel also tries to improve efficiency by limiting communication within the mesh by keeping repetitive messages passed to a minimum. When a node sends a message to the mesh, it sends it to the neighbors to which it is connected. These neighbors, in turn, inspect the message and then forward it to their neighbors; but they do not forward it to the neighbor from whom they got the message to start. In addition, a connection to a neighbor might be terminated if it keeps trying to resend a message that has been processed previously. Internally, each node keeps a local cache of the WS-Addressing message ID and the ID of the neighbor that delivered that message. This allows an optimized mesh network that does not waste resources with repeating data. A node can send messages to a subset of the mesh by assigning a hop count to the message. A hop count keeps a count of the number of nodes to which a message has been forwarded. This count is expressed as an integer within the message header and is decremented with each hop until it reaches a value of zero, after which it is not forwarded.

QuickReturnTraderChat Application
To get a better understanding of how everything comes together with the peer channel, let us start with a simple application that is called QuickReturnTraderChat. We have a few traders who are spread across a stock exchange and need the ability to chat with each other. The exchange, being a secure environment, does not allow any access to IM clients and wants to use the QuickReturnTraderChat application to allow talking to each other. This application allows more than one trader to broadcast a message to the other traderssimilar to an IRC channel. You will look first at the unsecured version of this sample, and then later make it secure, so that no one else can eavesdrop on the conversation. The application is simple and is implemented as a Windows application that contains one form. For clarity, we will not show the Windows Form boilerplate code, so that you can concentrate on the peer-channel aspects.

msdn.microsoft.com/en-us/library/cc297274.aspx

4/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Message Interface
A peer-channel service contract is just a WCF service contract in which the OperationContract attribute is defined in one way, as shown in Listing 1. The interface is called IQuickReturnTraderChat and has only one operation, which is called Say and accepts two parameters: user and message.

[evcCnrc(] Srieotat) pbi itraeIucRtrTaeCa ulc nefc Qikeunrdrht { [prtoCnrc(snWy=tu) OeainotatIOea re] vi Sysrn ue,srn msae; od a(tig sr tig esg) }

Listing 1. IQuickReturnTraderChat service contract

Service Configuration
Listing 2 shows the service side of the configuration. This application listens at the net.p2p://QuickReturnTraderChat address. Being a P2P application, its binding is set to netPeerTcpBinding and the contract for the endpoint is set to QuickReturnTraderChat.IQuickReturnTraderChat (following the namespace.interface format). The binding configuration is intentionally kept separate and is shown later in Listing 3.

<evc nm=QikeunrdrhtMi" srie ae"ucRtrTaeCa.an> <ot hs> <aedrse> bsAdess <d bsAdes"e.2:/ucRtrTaeCa"> ad aedrs=ntpp/Qikeunrdrht/ <bsAdess /aedrse> <hs> /ot <npit edon nm=Qikrdrht ae"ucTaeCa" ades" drs=" bnig"ePeTpidn" idn=ntercBnig bnigofgrto=Bnigneue idnCniuain"idnUscr" cnrc=QikeunrdrhtIucRtrTaeCa" otat"ucRtrTaeCa.Qikeunrdrht / > <srie /evc>

Listing 2. Service configuration

Binding-Configuration File
As we stated earlier, a P2P applications binding is set to netPeerTcpBinding, and the resolver mode is set to PNRP. Because this application is not secure, we have the security mode switched off by setting it to None.

<idns bnig> <ePeTpidn> ntercBnig <idn nm=Bnigneue> bnig ae"idnUscr" <euiymd=Nn"> scrt oe"oe/ <eovrmd=Pr"> rsle oe"np/ <bnig /idn> <ntercBnig /ePeTpidn> <bnig> /idns
msdn.microsoft.com/en-us/library/cc297274.aspx 5/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Listing 3. Binding configuration

Main Application
The main application that is shown in Figure 1 consists of a Windows Form that has two text boxes: one for the message that is being sent (called textBoxMessage), and one to show the conversation (called textBoxChat). The form contains also one button (called buttonSend).

Figure 1. QuickReturnTraderChat application The class that implements the Windows Form is called Main and is implemented as is shown in Listing 4. This form inherits from the .NET Form class and also implements the IQuickReturnTraderChat interface that was defined earlier. Because this is a WCF Service, the class is decorated with the ServiceBehavior attributethe InstanceContextMode controlling when a new Service object should be created. In our case, we want this to behave as a singleton; as a result, the InstanceContextMode is set to Single.

[evcBhvo(ntneotxMd =IsacCnetoeSnl) SrieeairIsacCnetoe ntneotxMd.ige] pbi prilcasMi :Fr,IucRtrTaeCa ulc ata ls an om Qikeunrdrht { }

Listing 4. Service-host class definition As shown in Listing 5, the Main class implements two methodsStartService and StopServicethat start and stop, respectively, the service host (as the names suggest). The Main class also has a few member variables that expose the Channel, ServiceHost, and ChannelFactory.

IucRtrTaeCa canl Qikeunrdrht hne; Srieoths =nl; evcHs ot ul Canlatr<Qikeunrdrht canlatr =nl; hneFcoyIucRtrTaeCa> hneFcoy ul srn ueI ="; tig srD " piaevi Satevc( rvt od trSrie) { /IsataenwSrieot /ntnit e evcHs hs =nwSrieotti) ot e evcHs(hs;
msdn.microsoft.com/en-us/library/cc297274.aspx 6/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

} piaevi SoSrie) rvt od tpevc( { i (ot! nl){ f hs = ul canlSy"di" "* Ue "+ueI +"Laig**"+ hne.a(Amn, ** sr srD evn ** EvrnetNwie; niomn.eLn) i (otSae! Cmuiaintt.lsd { f hs.tt = omnctoSaeCoe) canlatr.ls(; hneFcoyCoe) hs.ls(; otCoe) } } }

/Oe Srieot /pn evcHs hs.pn) otOe(; /Cet aCanlatr adla tecniuainstig /rae hneFcoy n od h ofgrto etn canlatr =nwCanlatr<Qikeunrdrht hneFcoy e hneFcoyIucRtrTaeCa> (Qikrdrhtnpit) "ucTaeCaEdon"; canl=canlatr.raehne(; hne hneFcoyCetCanl) /Lt ohr ko ta smoenwhsjie /es tes nw ht oen e a ond canlSy"di" "* NwUe "+ueI +"Jie **"+ hne.a(Amn, ** e sr srD ond ** EvrnetNwie; niomn.eLn)

Listing 5. Service-host implementation

IQuickReturnTraderChat Implementation (the Receiver)


We have both the service side and the receiver side of things in the same class. The configuration for the receiver is shown in Listing 6; it is quite similar to the sender configuration and uses the same binding.

<let cin> <npit edon nm=Qikrdrhtnpit ae"ucTaeCaEdon" ades"e.2:/ucRtrTaeCa" drs=ntpp/Qikeunrdrht bnig"ePeTpidn" idn=ntercBnig bnigofgrto=Bnigneue idnCniuain"idnUscr" cnrc=QikeunrdrhtIucRtrTaeCa" otat"ucRtrTaeCa.Qikeunrdrht / >

Listing 6. Receiver configuration The receiver here is fairly simple; all it does is echo out the message to the chat text box on the Windows Form, as shown in Listing 7.

vi IucRtrTaeCa.a(tigue,srn msae od QikeunrdrhtSysrn sr tig esg) { txBxhtTx + ue +"sy:"+msae etoCa.et = sr as esg; }

Listing 7. Receiver implementation

Invoking the Service


The service is invoked in the Click event of the Send button, as shown in Listing 8. The second line is where we invoke service. If you recall, channel is of type IQuickReturnTraderChat and is defined in the Main class (shown in Listing 4).
msdn.microsoft.com/en-us/library/cc297274.aspx 7/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

piaevi btoSn_lc(betsne,Eetrse rvt od utnedCikojc edr vnAg ) { srn tm =txBxesg.et+EvrnetNwie tig ep etoMsaeTx niomn.eLn; /Ivk teSrie /noe h evc canlSyueI,tm) hne.a(srD ep; txBxesg.la(; etoMsaeCer) }

Listing 8. Service invocation As you can see, creating a simple P2P application by using WCF is fairly trivial, and you do not need to do anything with the Windows P2P Networking stack. Our QuickReturnTraderChat application has been kept fairly simple, to show you the concept and how to implement a P2P application.

P2P Security
Security in a P2P network is an interesting challenge. As far as an application is concerned, when securing a P2P network, there are two points of interest. Firstly, only authorized users get on the network. Secondly, the message that you received originated from a known and trusted source, and the message itself has not been tampered with during transmission. The first aspect is relatively easy to achieve: When a new application or user logs on to the mesh, that application or user can be challenged to authenticate before being allowed to join the mesh. The second aspect is a little more difficult, because you are not directly connected to another peer in the mesh. However, with WCF, this is relatively straightforward, because the NetPeerTcpBinding class exposes the PeerSecuritySettings class via the Security property. So, how does it all come together with WCF? For OutputChannels, which reside on the sender, each message that is sent is signed by using a certificate; and all messages, before being sent to an application, are validated for this credential. The certificate that is needed is provided by using the PeerCredential.Certificate property. The validation that was stated earlier can be implemented via an instance of the X509CertificateValidator class, which is provided as part of the PeerCredential.MessageSenderAuthentication property. When the message arrives on the other end, the peer channel ensures the validity of the message before forwarding it up the chain to the application.

Peer-Channel Security
You specify the security settings for the peer channel by using the Security property, which is available on the NetPeerTcpBinding class. This property operates like any other standard binding in WCF. You can apply four types of security at this level, and they are exposed via the Mode property; the underlying class is in the PeerSecuritySettings class. These four options for security are the following: NoneNo security is required. TransportNo message security is implemented; only neighbor-to-neighbor security is required. MessageOnly message authentication is required when communicating over an open channel. TransportWithMessageCredentialThis is essentially a combination of Transport and Message (defined previously). It would require that the message be secure and that authentication be required over secure neighbor-to-neighbor channels. Note: If security is enabled on the binding and is set to Message or TransportWithMessageCredential, messages that pass through both on the outbound and on the inbound must be secured by using X509Certificate. The PeerChannel class provides two ways to authenticate two peers, which are configured by using the PeerTransportSecurityElement.CredentialType property. This is either Password or Certificate. When this is set to Password, every peer needs a password to
msdn.microsoft.com/en-us/library/cc297274.aspx 8/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

connect. The owner of the mesh is responsible for setting the password initially and communicating it to peers whom you will allow to join the mesh. On the other hand, when this is set to Certificate, authentication is based on X509Certificate. When an application initiates a peer-channel instance, an instance of the peer-channel transport manager is started. The transport manager resolves the endpoint address of the requested peers and the mesh. PNRP acts as the default resolver for this; however, you can choose to implement a custom resolver, too. As soon as the address has been resolved, the transport manager initiates a connection request to each of the peers.

Password-Based Authentication
When using the password-based authentication, the steps that are used to initiate a connection with the transport manager are the same. The main difference is that when a peer initiates a connection request, the link between the two peers is over a SSL connection. Also, as the first step after initiating connection between the two peers, the initiator peer will send a custom handshake message that authenticates the password. If the responder peer is satisfied with this, it accepts the connection and sends a similar response to the originating peer. If the initiator peer is satisfied with this, the connection is established; if not, the connection is abandoned. This handshake must contain some metadata for it to function. The first piece of the metadata is the certificate with which the secure connection is established; the second metadata is the password with which the handshake is established. The PeerCredential class is exposed as the Peer property on the ChannelFactory.Credentials property. This is demonstrated in the secure version of the chat sample that was discussed earlier in the article. This secure version is called QuickReturnSecureTraderChat (youll see it a bit later).

Certificate-Based Authentication
When using the certificate-based authentication mode, the application has control of the authentication process, compared to the WCF runtime. There is no custom handshake involved; instead, the transport manager, after receiving the certificate, passes that on to the application to authenticate. To get this functionality, the application must provide a couple of certificates. The first certificate establishes the SSL connection and the identity between the peers. The second certificate provides a concrete implementation by the application for the abstract X509CertificateValidator class. This is also demonstrated in the secure version of the chat sample (youll see it a bit later).

Message Security
If you are interested in securing the message itself to ensure that it has not been tampered with during transmission, you must use the Message security option. Effectively, when this is requested, the peer channel on every outbound message includes a signature; vice versa, on every inbound message, it validates the signature. The signature is validated against the same certificate (without the specific private keys, of course). The signatures that are added to the message are compatible with all of the peers on the mesh. A peer channel can verify signatures that are specific to the application through a hook that allows you to participate in its signature-verification routine. This hook is in a concrete implementation of the abstract X509CertificateValidator class. This allows you to have any criteria for the pass or fail validation.

QuickReturnSecureTraderChat Sample
QuickReturnSecureTraderChat essentially is the same as the chat application that was discussed earlier, with the addition of security. For the sake of simplicity, this was implemented as a separate solution. In the real world, you would probably read the security information via a configuration setting; based on that, you would either enable or disable the security options. As discussed earlier, security can be set by using either a password or an X509 certificate. For our sample here, we will use a password; however, we will show how easy it is to change this to use a certificate.
msdn.microsoft.com/en-us/library/cc297274.aspx 9/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Service Configuration
The service side of the configuration that is shown in Listing 9 is very similar to the service configuration that was used in the earlier example. While the address and the namespace have been updated, the real configuration change is the use of a different binding type for the bindingConfiguration parameter.

<evc nm=QikeuneuerdrhtMi" srie ae"ucRtrScrTaeCa.an> <ot hs> <aedrse> bsAdess <d bsAdes"e.2:/ucRtrScrTaeCa"> ad aedrs=ntpp/Qikeuneuerdrht/ <bsAdess /aedrse> <hs> /ot <npit edon nm=QikrdrhteueasodnPit ae"ucTaeCaScrPswrEdon" ades" drs=" bnig"ePeTpidn" idn=ntercBnig bnigofgrto=Bnigeueasod idnCniuain"idnScrPswr" cnrc=QikeuneuerdrhtIucRtrTaeCa" otat"ucRtrScrTaeCa.Qikeunrdrht / > <srie /evc>

Listing 9. Service configuration

Binding Configuration
The updated binding configuration that is used by both the host and the client in our example is called BindingSecurePassword. The main difference between this and the previous example is the addition of the security details, as shown in Listing 10. As you can see, we have the security mode set to Transport and the type set to Password.

<idn nm=Bnigeueasod> bnig ae"idnScrPswr" <euiymd=Tasot> scrt oe"rnpr" <rnpr ceetaTp=Pswr"> tasot rdnilye"asod/ <scrt> /euiy <eovrmd=Pr"> rsle oe"np/ <bnig /idn>

Listing 10. Secure binding configuration

Main Application
The main application is the same as shown in Figure 1. The only difference between this and the earlier example is the addition of a new member variable to hold the password, which is read from the app.config file. Note: We recommend that you do not save the password in the app.config file in clear text, because anyone can open it and read the password. We recommend that you save the password in an encrypted storage, or accept the password from the user at run time. To hold the password in memory, use the SecureString class that was introduced in .NET Framework 2.0. The updated member variable that is used by the solution is shown in Listing 11. The channel is of type IQuickReturnTraderChat; this is the contract that was implemented by the service. The members that are named host and channelFactory are the service host and the channel factory, respectively. The two string variables respectively store the user and password, which are read from the app.config file by using ConfigurationManager.AppSettings in the constructor for our Main class.
msdn.microsoft.com/en-us/library/cc297274.aspx 10/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

IucRtrTaeCa canl Qikeunrdrht hne; Srieoths =nl; evcHs ot ul Canlatr<Qikeunrdrht canlatr =nl; hneFcoyIucRtrTaeCa> hneFcoy ul srn ueI ="; tig srD " srn pswr =nl; tig asod ul

Listing 11. Member-variable list The StartService method in the Main class has been updated slightly, as shown in Listing 12. This now uses a different endpoint configuration file and sets the password for both the host and the channel. The StopService method remains the same as earlier, and it is not listed again here. As shown in Listing 12, the password for both the host and the ChannelFactory is set via the Credentials.Peer.MeshPassword property. The binding configuration has been updated and is read from QuickTraderChatSecurePasswordEndPoint.

piaevi Satevc( rvt od trSrie) { /IsataenwSrieot /ntnit e evcHs hs =nwSrieotti) ot e evcHs(hs; /Sttepswr /e h asod hs.rdnil.erMsPswr =pswr; otCeetasPe.ehasod asod /Oe Srieot /pn evcHs hs.pn) otOe(; /Cet aCanlatr adla tecniuainstig /rae hneFcoy n od h ofgrto etn canlatr =nwCanlatr<Qikeunrdrht hneFcoy e hneFcoyIucRtrTaeCa> (QikrdrhteueasodnPit) "ucTaeCaScrPswrEdon"; /Sttepswr frteCanlatr /e h asod o h hneFcoy canlatr.rdnil.erMsPswr =pswr; hneFcoyCeetasPe.ehasod asod /Cet teCanl /rae h hne canl=canlatr.raehne(; hne hneFcoyCetCanl) /Lt ohr ko ta smoenwhsjie /es tes nw ht oen e a ond canlSy"di" "* NwUe "+ueI + hne.a(Amn, ** e sr srD "Jie **"+EvrnetNwie; ond ** niomn.eLn) }

Listing 12. Service-host implementation One interesting behavior with the security is that if you have a set of peers listening on the same endpoint, but with different passwords, they will be isolated from each other. For example, say that you have four usersUser1, User2, User3, and User4. User1 and User2 are chatting and connected to the mesh by using password1. If User3 and User4 start chatting with another passwordsay, password2even though all four users are on the mesh and listening on the same endpoint, the messages between User1 and User2 cannot be seen by Users3 and User4, and vice versa. To use an X509 certificate instead of a password to secure a mesh, set the transport credentialType in the binding to Certificate, and set the Credentials.Peer.Certificate property to Certificate on both the host and the client.

Peer Name
A peer, as we know, is the most basic building block of a P2P network and the final endpoint of the communication. A peer can be an application, computer, Windows service, and so on. A peer is defined by using the PeerName class, and, as we know, it can be either secure or unsecure.

Creating
Creating a new peer is quite straightforward by using the PeerName class. Listing 13 shows
msdn.microsoft.com/en-us/library/cc297274.aspx 11/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

an example of how to define both an unsecure peer and a secure peer. The PeerName class has three overloaded constructors; however, to create a new instance of a fully qualified peer, the third overload that accepts two parameters is the best option. The first parameter is the classifier, and the second parameter is the secure or unsecure peer.

PeNm mPe =nwPeNm(MUscrPe"PeNmTp.Uscrd; erae yer e erae"yneueer,eraeye neue) PeNm mScrPe =nwPeNm(MScrPe" erae yeueer e erae"yeueer, PeNmTp.eue) eraeyeScrd;

Listing 13. Peer definition A classifier is a string that refers to the peer name and does not guarantee uniqueness; that is, you can have more than one peer in the cloud with the same classifier. A peer name is case-sensitive. A secure peer automatically creates a 40-character-long hex string as the authority, which makes it difficult to spoof the peer. The authority for an unsecure peer is always set to 0 (zero). The authority for a peer can be retrieved via the Authority property.

Publishing
Creating a peer by itself is quite meaningless, so that the next logical step is to register (or publish) a peer and associate it with a cloud. A peer must be part of a cloud that will then enable it to communicate with other peers within the cloud. A cloud is no more than a collection of peers and is uniquely identified with a name. Clouds are closely tied to a network interface. In addition to the Global cloud, of which there is only one, each network card on a computer would have a cloud attached to it. For example, if you have a laptop that has a wired and a wireless network connection, there will be three clouds available: Global, and one for each of the network connections. Registering a peer is done by using the PeerNameRegisteration class, which has a few overloaded constructors. The three basic steps are as follows: 1. Peer that you are trying to register 2. TCP port over which the peer will listen 3. Endpoint that is affiliated with the peer You can use the EndPointCollection property of the PeerNameRegisteration class to add a new endpoint, which expects an IPEndPoint object. However, in most cases, we dont want to add a new endpoint explicitly; instead, we want to use the address that is assigned to the local computer that hosts the peer. To do so, we use the UseAutoEndPointSelection property; setting it to True will automatically pick up the endpoints when registering the peers. Listing 14 shows how to register the two peers that we had defined earlier.

PeNmRgsrto rgseain=nw eraeeitain eitrto e nmPe,00; (yer33) rgseainUeuonPiteeto =tu; eitrto.sAtEdonSlcin re rgseainSat) eitrto.tr(;

PeNmRgsrto eraeeitai

Listing 14. Peer registration The Start method registers the peer on the cloud. If a specific cloud is not specified via the Cloud property, the peer is registered on all of the clouds that are available to the client. By default, the port for PeerNameRegisteration is 0 (zero) and the UseAutoEndPointSelection property is set to True. Thus, the code in Listing 14 and Listing 15 are equivalent.

PeNmRgsrto rgseain=nwPeNmRgsrto(; eraeeitain eitrto e eraeeitain)


msdn.microsoft.com/en-us/library/cc297274.aspx 12/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

rgseainPeNm =mPe; eitrto.erae yer rgseainPr =33; eitrto.ot 00 rgseainSat) eitrto.tr(;

Listing 15. Peer registration It is also possible to associate one peer with multiple PeerNameRegisteration objects. If the peer is not secure, it can be registered in the same cloud multiple times, as long as each registration is from a different process on the operating system. On the other hand, if a peer is secure, every instance of the peer is registered in a different cloud. A peer that is registered in a cloud is identified via a PeerRecord object that also encapsulates all of the relevant details.

Resolving
The final logical step after creating and publishing a peer is resolving a peer. What good is it to publish something to the cloud if another peer cannot find you? We use the PeerNameResolver class to resolve for a specific peer in a given cloud. The PeerNameResolver can resolve a peer to either a PeerRecord or a cloud, depending on the parameters that are passed. The resolution process finishes either when the maximum number of record entries for the PeerRecordCollection is reached or when it has reached the end of various clouds. The PeerNameResolver class exposes an overloaded method that is called Resolve and is used to resolve a given peer synchronously. The scope of what will be resolved depends on the parameters that are passed. Also, because we cannot resolve a peer from the same process that published it, we have a simple console application that registers a secure peer and an unsecure peer on a cloud, as shown in Listing 16.

sai vi Mi(tig]ag) ttc od ansrn[ rs { PeNm mPe =nwPeNm(MUscrPe" erae yer e erae"yneueer, PeNmTp.neue) eraeyeUscrd; PeNm mScrPe =nwPeNm(MScrPe" erae yeueer e erae"yeueer, PeNmTp.eue eraeyeScrd ) ; PeNmRgsrto rgseain=nw eraeeitain eitrto e PeNmRgsrto(yer 33 eraeeitainmPe, 0 0; ) PeNmRgsrto rgseain =nw eraeeitain eitrto2 e PeNmRgsrto(yeuee eraeeitainmScrP e,33) r 00; rgseainSat) eitrto.tr(; rgseain.tr(; eitrto2Sat) CnoeWieie"eitrto o Pe {}cmpeewt te osl.rtLn(Rgseain f er 0 oelt ih h " mPe.otig) mPe.erotae; , yerTSrn(, yerPeHsNm) CnoeWieie"eitrto o Pe {}cmpeewt te osl.rtLn(Rgseain f er 0 oelt ih h " mScrPe.otig) mPe.erotae; , yeueerTSrn(, yerPeHsNm) CnoeWieie"rs aykyt cniu..) osl.rtLn(Pes n e o otne."; CnoeRaKy) osl.ede(; rgseainSo(; eitrto.tp) rgseain.tp) eitrto2So(; hsnm {} otae 1. hsnm {} otae 1.

Listing 16. Secure and unsecure peers registered Listing 17 shows us how to try to resolve for a peer that is called MySecurePeer. The Resolve method returns a collection of type PeerNameRecordCollection through which we iterate. Listing 18 shows the result of this when running on a computer that has three network cards.

msdn.microsoft.com/en-us/library/cc297274.aspx

13/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

PeNm mPe =nwPeNm(MScrPe" PeNmTp.eue) erae yer e erae"yeueer, eraeyeScrd; PeNmRsle rsle =nwPeNmRsle(; eraeeovr eovr e eraeeovr) PeNmRcrCleto rsls=rsle.eov(yer; eraeeodolcin eut eovrRslemPe) CnoeWieie"0 PesFud" rslsCutTSrn() osl.rtLn({} er on:, eut.on.otig); iti=1 n ; frah(eraeeodpe i rsls oec PeNmRcr er n eut) { CnoeWieie"0 Pe:1" i+ pe.eraeTSrn() osl.rtLn({} er{}, +, erPeNm.otig); frah(PnPiti i pe.nPitolcin oec IEdon p n erEdonCleto) { CnoeWieie"tEdon:{},i.otig); osl.rtLn(\ npit 0" pTSrn() } }

Listing 17. Resolving a peer on a cloud Because the peer that we are resolving is secure, we see a random 40-character hex string as the authority in the peer. The peer was originally published on all available network connections (we did not limit the scope and use the default). The computer on which this code was executed had three network cards; hence, we see four result setsone for each network adapter and the Global cloud. On the network adapters that have both IPv4 and IPv6, you see two endpoints.

4PesFud er on: 1Pe:4d6eb84efc60b036fe07MScrPe er49c4c23797e0da6622be.yeueer Edon:f8:86:57d5:ea1:00 npit e0:818c:26a5%533 Edon:121810133 npit 9.6.0.:00 2Pe:4d6eb84efc60b036fe07MScrPe er49c4c23797e0da6622be.yeueer Edon:51.9.333 npit .7187:00 3Pe:4d6eb84efc60b036fe07MScrPe er49c4c23797e0da6622be.yeueer Edon:f8:91:dd69:16933 npit e0:5825:696b%:00 Edon:19249.8:00 npit 6.5.71233 4Pe:4d6eb84efc60b036fe07MScrPe er49c4c23797e0da6622be.yeueer Edon:f8:5deb::1d1:00 npit e0:6:13922%333 Edon:12186.:00 npit 9.6.2133

Listing 18. Peer-resolution result

Clouds
Clouds are tightly integrated with the network interfaces on a computer. If there are n network interfaces, we will get n+1 cloudsone LinkLocal for every network interface, and one Global cloud. The System.Net.PeerToPeer namespace contains a static class that is called Cloud and can be used to interact with the cloud of a specific peer. This class has two static membersGetAvailableClouds and GetCloudByNamethat return a CloudCollection that contains all of the known clouds or the specific cloud, respectively. The Cloud class has a couple of interesting fieldsnamely, AllLinkLocal and Available. AllLinkLocalReturns a reference to a single cloud that represents all of the link-local clouds in which the peer is currently participating AvailableReturns a reference to a single cloud that represents all of the clouds in which the peer is currently participating Consider Listing 19, which lists all of the clouds and writes the result to the console. The result of this is shown in Listing 20.
msdn.microsoft.com/en-us/library/cc297274.aspx 14/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Codolcincod =CodGtvialCod(; luCleto lus lu.eAalbelus) CnoeWieie"0 cod fud"cod.on) osl.rtLn({} lus on.,lusCut; iti=1 n ; frah(lu smCodi cod) oec Cod oelu n lus { CnoeWieie"0:Nm:1" i+ smCodNm) osl.rtLn({} ae{}, +, oelu.ae; CnoeWieie"tcp I:0,Soe{}, osl.rtLn(\Soe D{} cp:1" ,oelu.cp) smCodSoe; }

smCodSoed oelu.cpI

Listing 19. List all available clouds

5cod fud lus on. 1 Nm:lbl : aeGoa_ SoeI:,SoeGoa cp D0 cp:lbl 2 Nm:ikoa_f0:1/ : aeLnLclf0:%58 SoeI:5 SoeLnLcl cp D1, cp:ikoa 3 Nm:ikoa_f0:1/ : aeLnLclf0:%38 SoeI:3 SoeLnLcl cp D1, cp:ikoa 4 Nm:ikoa_f0:88 : aeLnLclf0:%/ SoeI:,SoeLnLcl cp D8 cp:ikoa 5 Nm:ikoa_f0:98 : aeLnLclf0:%/ SoeI:,SoeLnLcl cp D9 cp:ikoa

Listing 20. List of available clouds

People Near Me and Contacts


People Near Me (PNM) is a new feature of Windows Vista, and provides a standard set of APIs that allow one to write applications that can interact and collaborate with other users on the local subnet. PNM provides four key servicesDiscover, Interact, Collaborate, Publishthat enable a user to share objects and applications, subscribe to events, and send invites for others to join. This section covers in detail only the Discover and Interact services of PNM.

Discover
Internally, PNM uses Web discovery to publish various details, such as name, computer name, IP address, port, and so on. A user is not signed in automatically; instead, a user signs in via the Control Panel. After having done so, a user can choose the option to sign in automatically whenever Windows starts. Figure 2 and Figure 3 show the PNM icon when a user is signed in and signed out, respectively.

Figure 2. PNM, signed in

Figure 3. PNM, signed out As shown in Figure 4, the Settings tab of PNM allows a user to sign in and out of PNR and
msdn.microsoft.com/en-us/library/cc297274.aspx 15/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

change settings, such as the friendly name that others will see, which profile of users one would want to accept invitations from, and so on.

Figure 4. People Near Me options A significant portion of the PNM functionality is provided by a static class that is called PeerCollaboration and can be found in the System.Net.PeerToPeer.Collaboration namespace. This class allows you to interact with the collaboration infrastructure, which enables one to sign in, sign out, register and unregister applications, and so on. PeerCollaboration has a static method that is called SignIn and with which one can sign in to the collaboration infrastructure, as shown in Listing 21. Note that you must have IPv6 installed for this to work; otherwise, you will get a PeerToPeerException that shows the message, The sign-in succeeded, but there are no IPv6 addresses available at this time. Each PNM is represented by the PeerNearMe class, which exposes all of the details for a peer, such as the endpoints at which they can be reached, nickname, whether they are online, and so on. After you have signed in, you can try to find any peers that are within the PNM infrastructure via the GetPeersNearMe method. This returns a collection of PeerNearMe that represents the peers who are signed-in in the same local subnet.

PeClaoainSgI(ercp.l) erolbrto.innPeSoeAl; PeNaMCleto pes=PeClaoainGterNaM(; erereolcin er erolbrto.ePesere) CnoeWieie"0 pesfud" pesCut; osl.rtLn({} er on., er.on)

Listing 21. Sign in to collaboration

Contacts
The other option for discovering people is to search in the Windows Address Book (WAB). The entries that are saved in the WAB are called as Contacts and enable interaction beyond the local subnet. The WAB is a new feature of Windows Vista. You can find the WAB saved as Contacts; it is usually stored in C:\Users\<user-name>\Contacts. The WAB features are exposed via a class that is called ContactManager and can be
msdn.microsoft.com/en-us/library/cc297274.aspx 16/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

retrieved via the PeerCollaboration class. The ContactManager class exposes a method that is called GetContacts and returns a collection of PeerContacts that are available in the signed-in scope, as shown in the following snippet:

Cnataae cnatg =PeClaoainCnataae; otcMngr otcMr erolbrto.otcMngr PeCnatolcincnat =cnatg.eCnat(; erotcCleto otcs otcMrGtotcs)

You can add a found peer to your address book by using the AddToContactManager() method on the PeerContact. If that peer already exists as a contact, you will get a PeerToPeerException that shows the message, Peer collaboration add contact failed. Contact already exists in contact manager. Listing 22 shows the code and the output when there is one more peer called Amit2 on the subnet. Figure 5 shows what the contact looks like when it is added to the WAB.

PeNaMCleto pes=PeClaoainGterNaM(; erereolcin er erolbrto.ePesere) CnoeWieie"0 pesfud" pesCut; osl.rtLn({} er on., er.on) frah(ererepe i pes oec PeNaM er n er) { PeCnatcnat=pe.dTCnataae(; erotc otc erAdootcMngr) CnoeWieie"er{}i oln:1 wt {}edons, osl.rtLn(Pe 0 s nie{} ih 2 npit" pe.snie pe.ernPit.on) erIOln, erPeEdonsCut; } 1pesfud er on. 1 Pe Ai2i oln:rewt 1edons : er mt s nieTu ih npit

pe.ikae erNcnm,

Listing 22. Peers found on the subnet

Figure 5. Contact added to Windows Address Book

Interact
To interact with another peer by using some application (typically, a line-of-business (LOB) application), the same application must be installed on both of the computersin other words, on yours and on the peer with whom you are planning to interact. Furthermore, this
msdn.microsoft.com/en-us/library/cc297274.aspx 17/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

application must be installed on both the computers with the same GUID and must be registered with the peer-collaboration infrastructure as one of the applications that is available for interaction. To find the endpoint at which an application can be reached, you can use the EndPoint property of the PeerNearMe class. This property returns an IPEndPoint object. The invitation that a user sends to a peer to launch a certain application contains an XML payload and is sent over a secure connection. The XML payload consists of the following: A unique GUID that identifies the application A user-defined message that is displayed to the peer who receives the invitation Additional data that essentially is a placeholder in which to put any blob of data that the target application might expect (for example, the endpoint details of the peer who sends the invitation) Figure 6 shows an example of what the invitation looks like on the target computer when one is inviting to launch Windows Meeting Space. This request is from an unknown peer. (If this were from a known contactthat is, part of WABthe request would look like what is shown in Figure 8.)

Figure 6. Unknown-peer invitation Clicking the View button shows the details of the invitation that is shown in Figure 7. If you accept the invitation, the application will launch. At this point, the peer infrastructure is no longer part of the process; instead, the applications that are on both ends are communicating by using regular communication protocols, such as TCP, HTTP, and so on.

Figure 7. Unknown Windows Meeting Space invitation details The GetLocalRegisteredApplications method on the PeerCollaboration class returns a collection of type PeerApplications that represents all of the applications that are registered on the local computer. By default, this method returns the applications that are registered for all users; however, if you want to restrict that to the logged-on user, you can use the overloaded method that accepts a PeerApplicationRegisterationType. Listing 23 shows a sample listing of the applications. It is this list of applications that is
msdn.microsoft.com/en-us/library/cc297274.aspx 18/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

available for a peer to use.

PeApiainolcinap =PeClaoainGtoaRgseeApiain(; erplctoCleto ps erolbrto.eLcleitrdplctos) iti=1 n ; CnoeWieie"0 Apiain Fud" ap.on) osl.rtLn({} plctos on:, psCut; frah(erplcto smApi ap) oec PeApiain oep n ps { CnoeWieie"t0:I:1" i smApI) osl.rtLn(\{} D{}, , oep.d; CnoeWieie"ttec{},smApDsrpin; osl.rtLn(\\Ds:0" oep.ecito) CnoeWieie"ttah{},smApPt) osl.rtLn(\\Pt:0" oep.ah; CnoeWieie"ttruet:0" smApCmadiers; osl.rtLn(\\Agmns{}, oep.omnLnAg) }

Listing 23. Iterating through all available peer applications You use the Invite() method on the PeerNearMe class to invite a selected peer to launch the application. This method takes three parameters: the application that is to be launched, a message for the user, and some data (as shown in Listing 24). The data parameter is specific for each application; based on its implementation, only the application knows what to expect. In many cases, it would contain your endpoint address, so that the application knows the address to which to talk back. The Invite() method returns a PeerInvitationReponse and can be one of the following options: Declined Accepted Expired

PeIvttoRsos rsos =pe.niemAp "att wr o ti PPatcet erniainepne epne erIvt(yp, Wn o ok n hs 2 ril oehr" nl) gte?, ul; i (epnePeIvttoRsosTp ! PeIvttoRsosTp.cetd f rsos.erniainepneye = erniainepneyeAcpe) Msaeo.hwpe.ikae+"dcie terqet"; esgBxSo(erNcnm elnd h eus.)

Listing 24. Inviting a peer to launch an application Figure 8 shows an invitation from a trusted contact to launch Windows Meeting Space. Clicking on the View button shows you the details of the invitation that is shown in Figure 9.

Figure 8. Known-peer invitation

msdn.microsoft.com/en-us/library/cc297274.aspx

19/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Figure 9. Known Windows Meeting Space invitation details

Creating Your PeerApplication


A PeerApplication can be any application that can run on Windows. The only difference between a regular application and a peer application is that the latter is registered as available on the P2P infrastructure. Typically, an application is registered during the installation process. Registering a new application manually or programmatically is fairly straightforward. The first step is to create a new instance of the PeerApplication class, and the second step is to register that instance on the P2P infrastructure. We need a unique ID (represented by a GUID) to identify this application. This ID must be the same on all of the computers on which this application will be installed and is used to identify the application that is to be launched on the target computer. In addition to the path of the executable and a human-readable description, we also must assign a scope to the application. Typically, this scope is dictated by the design of the application and what it is supposed to be doing. Listing 25 shows an example of creating a new PeerApplication that configures Microsoft Notepad to be available as part of the P2P infrastructure.

PeApiainmApiain=nwPeApiain) erplcto yplcto e erplcto(; mApiainDsrpin="yTs Apiain; yplcto.ecito M et plcto" mApiainI =nwGi(BC92-9A41-A7089E22"; yplcto.d e ud"021238-468A-AAA8B3) mApiainPt =@c\idw\oea.x" yplcto.ah ":wnosntpdee; mApiainPeSoe=PeSoeAl yplcto.ercp ercp.l;

Listing 25. Creating a new PeerApplication The third step is to register the application on the P2P infrastructure by using the RegisterApplication method on the PeerCollaboration class. This accepts two parameters: the application that you want to register, and the scope of the users for which the application is available (that is, the currently logged-on user or All Users). A PeerToPeerException is thrown if the registration fails.

PeClaoainRgseApiainmApiain PeApiaineitainyeCr erolbrto.eitrplcto(yplcto, erplctoRgsrtoTp.u rnUe) etsr;


msdn.microsoft.com/en-us/library/cc297274.aspx 20/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

The same application can be registered many times, as long as a unique ID is associated with each registration. For example, Listing 26 shows a sample output of all of the locally registered peer applications. Note that we have Notepad registered twice, with two different IDs.

3Apiain Fud plctos on: 1 I:1adec6-30b6-78a44a : D8fc1-7143-5ca2632a Ds:mtTs Apiain ecAi et plcto Pt::wnosntpdee ahc\idw\oea.x Agmns ruet: 1 I:021238-468a-aaa8b3 : Dbc92-9a41-a7089e22 Ds:mtTs Apiain ecAi et plcto Pt::wnosntpdee ahc\idw\oea.x Agmns ruet: 1 I:5992cc-2389-1d44ac : D139c-e743-5989c800 Ds:idw MeigSae ecWnos etn pc Pt::PormFlsWnosClaoainWnolbee ahC\rga ie\idw olbrto\iCla.x Agmns/ ruet:e

Listing 26. Sample output of locally registered applications If you are trying to register an application that will be available for All Users, the process that is executing this requires administrator privileges, because this writes to the registry. If you dont run this with elevated privileges, the registration will fail and throw a PeerToPeerException that shows the message, Peer collaboration register application failed. However, if you examine the inner exception, you see the more meaningful message of Access Denied. Of course, if you have User Account Control (UAC) switched off, you already are running with administrator privileges, and the registration will succeed.

PeClaoainRgseApiainmApiain PeApiaineitainyeAl erolbrto.eitrplcto(yplcto, erplctoRgsrtoTp.l Ues; sr)

As mentioned earlier, an application that is designed to be invoked over a peer infrastructure (such as Windows Meeting Space) typically would be registered during the installation process of that application. If you want to register this manually or if you are creating the setup (for example, by using the Setup and Deployment project in Microsoft Visual Studio or WiX), you must create an entry in the following Windows registry hives, depending on the scope. If the application is available for All Users, you must register it in the HKLM hive. If the application is available only for the current user, you must use the HKCU hive. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PeerNet\AppInvite\MyApplications HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PeerNet\AppInvite\MyApplications Each application is a new key that consists of the applications ID and the structure, as shown in the following snippet and in Figure 10:

"omnLnAg"" Cmadiers=" "ulctoSoe=wr:0002 Pbiaincp"dod0000 "ieae=C\Wnos\oea.x" Flnm"":\idw\ntpdee "ecito""oeAp Dsrpin=Sm p"

msdn.microsoft.com/en-us/library/cc297274.aspx

21/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Figure 10. Registry details of an application registered on the peer infrastructure If you accidentally use the same ID for two different applications, each of which is in a different scope (that is, Local User and All Users), the application that is found in Local User takes precedence. For example, if the 81facd1e-c761-4330-b56c-a7286a3424aa key is used to register both Notepad and UltraEdit in the All Users and Current User scopes, respectively, when iterating through the available list of registered applications, you will find only the reference to UltraEdit, because that takes precedence over the reference to Notepad. If you tried to register an application by using an existing ID in the same scope, you will get an exception that says that the application was already registered. Also, if the application on the target system was not found (for example, there might be a typing error in the path of the executable), you will get an Unable to start the program error message, as shown in Figure 11.

Figure 11. Peer application not found If your peer application needs some metadata at startupsuch as how is it launched, or to read any initial data such as any LOB-specific details or endpoint details, and so onyou must use the ApplicationLaunchInfo method on the PeerCollaboration class to get those details. One of the parameters on the Invite() method (shown in Listing 24) accepts this metadata and passes it through. Listing 27 shows an example of this.

PeApiainanhnolucIf =PeClaoainApiainanhno erplctoLucIf anhno erolbrto.plctoLucIf; i (anhno! nl) f lucIf = ul { SrnBidrs=nwSrnBidr) tigule e tigule(; sApn(Msae"+lucIf.esg +EvrnetNwie; .ped"esg: anhnoMsae niomn.eLn) sApn(PeApiain"+lucIf.erplcto.otig) .ped"erplcto: anhnoPeApiainTSrn( +EvrnetNwie; niomn.eLn) sApn(Pe Cnat"+lucIf.erotc.otig)+ .ped"er otc: anhnoPeCnatTSrn( EvrnetNwie; niomn.eLn) sApn(anhnoTSrn() .pedlucIf.otig); Msaeo.hwsTSrn() esgBxSo(.otig); }

Listing 27. Finding out application-launch details


msdn.microsoft.com/en-us/library/cc297274.aspx 22/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

If you want to respect the context of a peer and get its presence information, based on which you want to make some business decision (such as to initiate a session with another peer, if it is busy), use the LocalPresenceInfo property that is exposed by the PeerCollaboration class. This returns an object of type PeerPresenceInfo that exposes the PeerPresenceStatus enumeration.

Working with NetShell


NetShell, also known as netsh, is an indispensable command-line utility for anyone who works with P2P. Although netsh is primarily aimed at administrators, allowing them to administer network services, it is equally useful to a developer. To start netsh, open a command prompt, and then type netsh. Note: NetShell is available only when the P2P networking option is installed in Windows XP. By default, NetShell is installed on Windows Vista; however, for it to work, you must allow it as an exception in the firewall. The commands in netsh work with the concept of a context that determines the networking aspect within which you want to operate and accumulates various possible commands in that context. In most situations, you would switch to some context for the specific operation in which you are interested. Contexts can have subcontexts, and these, in turn, can have further subcontextsforming a tree-like hierarchy. Figure 12 shows how we switch the context to P2P PNRP Cloud.

Figure 12. netsh context The commands that you enter in netsh factor into the context on which you are working. For example, the show command that is entered (see Figure 12) knows that the context is cloud within a PNRP network and shows the commands for that context. You can switch from one context to another at any time.

Listing Clouds
If you want to see the clouds to which you are currently connected, you will use the show list command, as shown in Figure 13. In this example, you can see two clouds, where one of those clouds is synchronizing. Later, you will see when the cloud has finished synchronizing.

msdn.microsoft.com/en-us/library/cc297274.aspx

23/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Figure 13. Listing of clouds To see the configuration and status of the cloud, you use the show initialization command (or show init, in its short form). If a computer is connected to the Internet, it is part of the global cloud that is called Global_. If a cloud is connected to one or two LANs, individual clouds are available for each network adapter (or link). As its name suggests, scope (see Figure 13) represents the scope of the cloud and essentially shows the PNRPCLOUDINFO data structure that is part of the P2P SDK. The following list defines each of the columns that are defined in PNRPCLOUDINFO: ScopeThe scope of the cloud. It can be one of four values, from 0 to 3. Each of these values is described in the next section. IdThe unique identifier for that cloud. StateThe state of the cloud. It is represented by the PNRP_CLOUD_STATE structure in the SDK. This can be one of eight values and is described in the next section.

Cloud Scopes
The scope of a cloud can be one of the four values that are shown in the following list: 0The 1The 2The 3The cloud cloud cloud cloud can be in any scope (represented by PNRP_SCOPE_ANY). is a global scope (represented by PNRP _GLOBAL_ SCOPE). is a site-local scope (represented by PNRP_SITE_LOCAL_SCOPE). is a link-local scope (represented by PNRP_LINK_LOCAL_SCOPE).

The state of a cloud can be one of the eight values that are shown in the following list: VirtualThe cloud is not yet initialized. SynchronizingThe cloud is in the process of being initialized, but is not active yet. ActiveThe cloud is active. DeadThe cloud has lost its connection to the network, but was initialized. ActiveThe cloud is active. DisabledThe cloud is disabled in the registry. No NetThe cloud has lost its connection to the network, but was active. AloneThe cloud is in stand-alone mode.

Listing Peers in a Cloud


To see the locally registered nodes in a cloud, use the show names command in netsh. In the following example, we see that we have two peers that are identified as P2P Name and are connected to the cloud. Note that the exact list of peers that you see will of course be different from the ones that are shown (if the QuickReturnTraderChat application has been running from earlier, you should see that).

PPNm: 2 ae

0qikeunrdrht .ucrtrtaeca
24/32

msdn.microsoft.com/en-us/library/cc297274.aspx

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Iett: dniy Cmet omn: PR I: NP D Sae tt: I Adess P drse: PPNm: 2 ae Iett: dniy Cmet omn: PR I: NP D O K

26f447601f50fe34d2d0.nprtcl2 404f5b716579362d1a7ePrPoooV a???? ????? c24937d291cffe87.bc4619f7d501f8b8 f8a1c688f64eb1ba5caca00391bf2c90 O K 121817:18 tp 9.6..3199 c [0100:16e7:8713:8dd5]199tp 20:0043:3a24:75a3:c5:18 c 0783908 .87514 26f447601f50fe34d2d0.nprtcl2 404f5b716579362d1a7ePrPoooV LclMcieI oa ahn d a15a333d9184ecd0.7060504096e7bbbctt: dd5a4d5fd13333e970605040f5cd46e3Sae

Listing 28. Peer listing P2P NameName of the peer that is connected to the cloud. In our preceding example, the first peer, 0.quickreturntraderchat, is the QuickReturnTraderChat application that was discussed earlier. IdentityRepresents the identities, as the name suggests. Note that the identity of both of the peers is the same. This is so, because these peers are unsecure, and the default identity is used for them. PNRP IDRepresents the corresponding 256-bit PNRP ID. IP AddressesRepresents the endpoints (including the ports) that are associated with this peer.

Cloud Statistics
To see the cloud statistics, enter the show statistics command (the abbreviated command show stat will work, too) in netsh. This will display the statistics for all of the active clouds. For example, Listing 29 lists statistics for the global cloud. Although most of the entries are self-explanatory, the IP Addresses column is a list of the addresses that is used to connect to the cloud.

I Adess [0100:16e7:8713:8dd5]34 P drse: 20:0043:3a24:75a3:c5:50 Nme o cceetis 3 ubr f ah nre: 4 Etmtdcodsz:12 siae lu ie 4 Nme o rgsee nms 3 ubr f eitrd ae: Trtldrsle:0 hote eovs Trtldslct:0 hote oiis Trtldfod:0 hote los Trtldrpis 0 hote ear:

Listing 29. Cloud statistics There are more commands within the cloud context; to give you a basic understanding, we discussed only the more important ones. We encourage you to use the documentation and the SDK to explore other commands in netsh.

Working with Peers


To switch to the peer context from within PNRP, just type peer in netsh. The peers context, as the name suggests, allows you to work with peers and gives you the ability to add, delete, and enumerate entries, among other things. We will not be covering all of the commandsjust a couple of the more interesting ones. As you know, before one peer can talk to another peer, it must resolve that peer. To do this with netsh, you use the resolve commandpassing it the peer name. In this example, if you try to resolve the peer that is called 0.quickreturntraderchat, you get the result from Listing 30.

msdn.microsoft.com/en-us/library/cc297274.aspx

25/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

nthpppr pe>eov 0qikeunrdrht es 2 np errsle .ucrtrtaeca Rslesatd. eov tre.. Fud on: Cmet a???? omn: D???? Adess [e000:0000:9e4e:04ec]8235 drse: f8:0000:007a:f7e3:a7%:86 Etne pyod(iay: xedd ala bnr) Cmet a???? omn: D???? Adess [e000:0000:9e4e:04ec]8216 drse: f8:0000:007a:f7e3:a7%:83 Etne pyod(iay: xedd ala bnr) Cmet a???? omn: D???? Adess 192422235 drse: 6.5..:86 121817:86 9.6..3235 [0100:16e7:8713:8dd5]0235 20:0043:3a24:75a3:c5%:86 Etne pyod(iay: xedd ala bnr)

Listing 30. Peer resolution As you can see in the preceding example, two instances of the QuickReturnTraderChat application are running. Also, there are two network cardsone of which is connected to the Internet, and one of which is on an internal network. The first network adapter (which is connected to the Internet connection) has the IP address of 192.168.1.73 (after NAT, of course), and the local one has the IP address of 169.254.2.2both of which are listening on port 28365. The other command of interest is the traceroute command, which resolves a peer with path tracing. If the name is registered, the result will be quite similar to the resolve command that was used earlier, as shown in Listing 31.

nthpppr pe>rcrue0qikeunrdrhtGoa_ es 2 np ertaeot .ucrtrtaeca lbl Rslesatd. eov tre.. Fud on: Adess 192422235tp drse: 6.5..:86 c 121817:86 tp 9.6..3235 c [0100:16e7:8713:8dd5]0235 20:0043:3a24:75a3:c5%:86 tp c Etne pyod(tig: xedd ala srn) Etne pyod(iay: xedd ala bnr) RslePt: eov ah [0100:16e7:8713:8dd5]34,() () 20:0043:3a24:75a3:c5:50 0, 0 Acpe cetd [0100:16e7:8713:8dd5]34,() () 20:0043:3a24:75a3:c5:50 0, 0 Acpe FnlIqie cetd ia nur

Listing 31. Known-peer trace route If, on the other hand, the peer is not registered, we will see a more interesting behavior, as shown in Listing 32. Note that an invalid name (0.quickreturntraderchatwedontkow) is provided to mimic this behavior. Also, Listing 32 has been abbreviated for clarity. The exact number of hops would vary, depending on the size of your cloud.

nthpppr pe>rcrue0qikeunrdrhteoto Goa_ es 2 np ertaeot .ucrtrtaecawdnkw lbl Rslesatd. eov tre.. NtFud o on. RslePt: eov ah [0100:16e7:8713:8dd5]34,() () 20:0043:3a24:75a3:c5:50 0, 0 Acpe cetd [0100:16e7:4b2c:fa33]34,() (1 20:0043:3e10:65af:04:50 8, 3) Rjce (eded eetd Da n) [0100:16e7:4b16:bbf9]34,() (4) 20:0043:3e24:e5ad:24:50 7, 10
msdn.microsoft.com/en-us/library/cc297274.aspx 26/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Rjce (eded eetd Da n) [0100:16e7:c519:e2fa]34,() (1) 20:0043:3e17:babf:53:50 4, 32 Acpe Ssiiu cetd upcos [0100:16e7:c10f:31c0]34,() (00 20:0043:3e03:7855:f6:50 4, 20) Rjce (necal) eetd Urahbe [0100:16e7:c519:e2fa]34,() (2) 20:0043:3e17:babf:53:50 4, 15 Rjce (eded eetd Da n) [0100:16e7:8f10:d19b]34,() (9) 20:0043:3a34:95be:1e:50 4, 27 Rjce (eded eetd Da n) [0100:16e7:c427:75ed]34,() (8 20:0043:381b:10a9:b9:50 3, 7) Rjce (eded eetd Da n) [0100:16e7:c53e:7f90]34,() (0) 20:0043:3a02:4fee:e9:50 2, 23 Acpe cetd

Listing 32. Unknown-peer trace route

Debugging Tips
Windows XP and Windows Vista
If you cannot get a computer that is running Windows XP to talk to another computer, check to see if the PNRP is installed. Also, if the target computer is running Windows Vista, you might have to upgrade to PNRP version 2.0. Windows XP ships with PNRP version 1.0, which is not compatible with PNRP version 2.0 (the latter version ships with Windows Vista). To enable PNRP on Windows XP, perform the following steps: 1. 2. 3. 4. Go to Add/Remove Programs. Select Add/Remove Windows Components. Select Networking Details, and then click Details. Select Peer to Peer, and then click OK.

As soon as you have enabled PNRP, you must upgrade to version 2.0 by downloading the update from http://support.microsoft.com/default.aspx/kb/920342. However, note that you must have Windows XP SP2 applied to install this update. To test whether PNRP is installed and working correctly, you can list the clouds to which you are connected by opening a command prompt and running the following netsh command:

nthpppr codso ls es 2 np lu hw it

IPv6 Issues
If you are running Windows Vista (or Windows XP with PNRP 2.0 installed) and you dont see the Global_ cloud listed, as shown in Figure 14, it probably means that IPv6 is not working on the computer.

msdn.microsoft.com/en-us/library/cc297274.aspx

27/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Figure 14. Missing Global_ cloud The following list shows the possible status that the Global_ cloud can have: VirtualThe cloud has not finished initializing. No NetThe network connection has dropped (either the cable is unplugged or you are not in a Wi-Fi range anymore). ActiveAll is well, and you are connected to other peers. SynchronizingThe cloud is still bootstrapping (this is a quick process; it is quite rare for you to encounter this status). AloneYou are not reachable and cannot publish or resolve other peers. If you know that there are other peers on the network, a firewall might be blocking UDO ports 3540 and 1900. Check your seed server by using the netsh p2p pnrp cloud show seed Global_ command. (The default for Windows Vista is pnrpv2.ipv6.microsoft.com and pnrpv21.ipv6.microsoft.com.)

Registering a Name
If you want to register a peer name, you can use the netsh command, as shown in the following snippet. Figure 15 shows the result when it is run in a command prompt. Note that this registration is valid only for the life of the process (this is the netsh executable, in this case). You can use the netsh command to convert to host-name encoding also, as shown here:

nthpppr pe adrgsrto 0AiBhe Goa_ es 2 np er d eitain .mtare lbl nthpppr pe so cnetdae0AiBhe es 2 np er hw ovrenm .mtare

When you register a name, it is also recorded in the registry and can be found in the: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PeerNet\PNRP\MachineNamePublication\MachineName key.

msdn.microsoft.com/en-us/library/cc297274.aspx

28/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Figure 15. Registering a name

Seed Server
If you are having problems, you might want to try to ping the seed by using the p2p pnrp diag ping seed Global_ command. Although Microsoft owns pnrp.net, you can set up your own seed server, run a private PNRP cloud, and configure the peers to bootstrap from the custom clouds. There are two ways to change the seed server: Change the seed server setting in the registry to point to your seed server: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PeerNet\PNRP\IPV6-Global Override the Windows host file to point pnrpv2.ipv6.microsoft.com and pnrpv21.ipv6.microsoft.com to your seed server.

Bringing It All Together


To show all of the various elements that we discuss in this article, we have three simple applications that work in tandem. Two of these applications are the secure and unsecure implementations of our chat application. The last application is a Peer and Contact Explorer that shows you all of the PNMs on your subnet, as well as the Contacts in your WAB. If you choose to, you can also see more details of each of those entities, such as endpoint address, port, online status, and so on. As an example, Figure 16 shows that there is one another user who is called Amit2 and is logged on to the PNM infrastructure via the AMIT-VPC computer.

Figure 16. Peer and Contact Explorer


msdn.microsoft.com/en-us/library/cc297274.aspx 29/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Clicking Tools and then Options gives us a few more options, such as listing the Available Clouds and the peer applications that have been registered on this computer. As shown in Figure 17, you use this dialog box to register a new application for the P2P infrastructure. In our example, we are registering the QuickReturnTraderChat application. If you dont have a unique ID for this computer, you can generate one. Of course, if you do generate one, you must provide the same ID to other users, because it is this ID only that identifies the application to launch on the target computer.

Figure 17. Options dialog box Right-clicking on a specific peer gives us the option to invite them to start an application. Figures 18, 19, and 20 show us inviting another peer to launch the QuickReturnTraderChat application, the invitation that they accept, and the application finally being launched, respectively.

Figure 18. Inviting peer to launch an application

Figure 19. Invitation alert


msdn.microsoft.com/en-us/library/cc297274.aspx 30/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

Figure 20. Invitation details Figure 21 shows us two instances of the QuickReturnTraderChat application running on one computer, and a third instance running in a VM. It also shows us two other instances of the QuickReturnSecureTraderChat sample. Although both the unsecure and secure versions are running on the same computer, they cannot eavesdrop on each others messages.

Figure 21. Various application instances running in parallel

Conclusion
This article provides an understanding of the fundamentals of P2P and shows how to use the new features of WCFallowing us to build P2P applications by using managed code in .NET Framework 3.0. The article also introduces the new features of managing P2P networks, including using People Near Me and Windows Address Book, both of which are new features that are released as part of Windows Vista.

References
Peer-to-Peer Networking (MSDN Library)http://msdn2.microsoft.com/enus/library/ms899527.aspx Peer-to-Peer Application Development (MSDN Library) http://msdn2.microsoft.com/en-us/library/ms883403.aspx Peer-to-peer (Microsoft TechNet)http://technet.microsoft.com/enus/library/bb742623.aspx Microsoft Peer-to-Peer Networking (P2P blog)http://blogs.msdn.com/p2p/
msdn.microsoft.com/en-us/library/cc297274.aspx 31/32

06/07/2012

Peer-to-Peer Programming with WCF and .NET Framework 3.5

About the authors Amit Bahree is a Senior Solution Architect with Avanade and has over 14 years of experience in ITdeveloping and designing mission-critical systems. His background is a mixture of product development, embedded systems, and custom solutions across both public and private sectors. Amit has experience in a wide range of industry verticalsranging from financial services to utilities to insuranceand has implemented solutions for many Fortune 100 companies. For Amit, computers are a passion first, a hobby second, and a career third, and he is glad that he gets paid to do what he loves the most. He can be contacted via his blog at www.desigeek.com. Chris Peiris is an avid publisher in the application integration space and works for Avanade Australia as a Solutions Architect. He is a frequent speaker at professional developer conferences on Microsoft technologies. Chris has written many articles, reviews, and columns for various online publications, including MSDN, 15 Seconds, ASPToday, Wrox (Apress), and Developer Exchange (DevX). He has also coauthored many books on WCF, Web services, UDDI, C#, IIS, Java, and Security topics. Chriss current passions include WCF, .NET Framework 3.0, IBM Message Broker, Microsoft BizTalk, and other EAI implementations. His complete list of publications and contact details are available at http://www.chrispeiris.com.

Avanade is a global IT consultancy dedicated to using the Microsoft platform to help enterprises achieve profitable growth. Through proven solutions that extend Microsoft technologies, Avanade helps enterprises increase revenue, reduce costs, and reinvest in innovation to gain competitive advantage. Our consultants deliver value according to each customer's requirements, time line, and budget by combining insight, innovation, and the talent of our global workforce. Additional information can be found at www.avanade.com.

Did you find this helpful?

Yes

No

2012 Microsoft. All rights reserved.

msdn.microsoft.com/en-us/library/cc297274.aspx

32/32

Anda mungkin juga menyukai