I've been working with WCF (Windows Communication Foundation) and the new P2P-based PeerChannel lately.  I've learned a few things...

Listening on a port in Vista requires Administrator permissions.  For the PeerChannel this isn't necessary, but for net.tcp or http bindings you will need to have the elevated permissions.  Remember that in Vista it isn't enough to sign in with the Administrator account (unless you disable UAC).  You can explicitly Run as administrator by right-clicking on the EXE.  You can also modify the manifest to state higher requested privileges:

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker|highestAvailable|requireAdministrator"
uiAccess="true|false"/>
</requestedPrivileges>
</security>
</trustInfo>

This will automatically request elevation when the application is launched.  Otherwise operations will fail when the code tries to execute them.

For net.tcp, you will probably want the ability to run multiple applications without being fussy about the listening port.  By default, with no port specified, all net.tcp applications will attempt to listen on the same port, and of course, fail.  On the other hand, if you set PortSharingEnabled for the binding then they can effectively share the port.  This requires that the "Net TCP Port Sharing" service is enabled in Windows Services.  Then, applications don't directly listen on the socket.  Instead, Net.TCP Port Sharing service actually registers the listen URL (net.tcp://localhost/MySharedPort) and the "listening" application.  When requests come in, they get dispatched appropriately.  It's all transparent to the application and adds a lot of flexibility.  Read more here.

A big challenge was detecting when there were other nodes on the given mesh.  I would create the ServiceHost and client channel, send a join message, but different instances never saw it.  I initially figured out that if I added a delay after initialization, then sent the first message, everything worked.  That was too arbitrary so I kept looking.  The key is to use the PeerNode object.  From your client channel, get the underlying PeerNode, then you can check the IsOnline property, or subscribe to the Online and/or Offline events.  Online refers to you having connections to other peers, offline means you are isolated.  This is completely indepedent of your network connections, Internet access, etc.  Even two instances on the same machine will be offline until they reach out and connect to each other.

The confusing part of this was it never seemed to switch to Online.  I thought that it wasn't working, but it turned out (as far as I can tell) that until you try to send a message, it won't reach out.  If that's the case, then you can't wait for Online before sending the first message!  Instead, I initialize, send my join, then register for Online/Offline.  When Online triggers, I send another Join and all is well!

I found a few sites talking about PeerNode, but I couldn't get it working properly.  This is how I got it to work (Vista RC2): 

// Used to detect online status for mesh

PeerNode myPeerNode = ((IChannel)meshChannel).GetProperty<PeerNode>();

myPeerNode.Online += new EventHandler(myPeerNode_Online);

myPeerNode.Offline += new EventHandler(myPeerNode_Offline);

The event handlers can do anything, including update the UI assuming you used your Windows Form as your service object (add ServiceBehavior attribute and implement service methods).

There's still a lot about peers that I haven't touched on yet (including the actual P2P API), but PeerChannel is a good place to start.  Unfortunately I haven't been able to test it across machines yet.  It either requires an IPv6 LAN or it won't work between XP and Vista (I don't have two Vista machines up yet).  P2P is still mysterious!

For more information on the P2P API itself (especially using interop from C#) take a look at some articles on CodeProject from Adrian Moore.