c# 对等网络 对等机 P2P

一、P2P实现方案的核心:发现 连接 通信。

命名空间:System.Net.PeerToPeer;System.Net.PeerToPeer.Collaboration。

P2P概念的溢出。溢出是指单块数据库通过网络转播到所有对等机上的方式,或者在网络中查询其他节点以定位特定快数据的方式。

实现P2P的两种技术:

1.Peer Name Resolution Protocol(PNRP),它用于发布和解析对等机的地址。PNRP本身没有提供创建P2P应用程序所需的功能,而只是其中一种可用于

解析对等机地址的底层技术。要和WCF或者TCP等实现P2P的功能。

2.People Near Me(PNM)服务器,它用于定位本地的对等机(目前只能在Vista和Windows7中使用)。

二、PNRP服务可以使用两种类型的云:

1、本地链接和全局(Internet上的计算机)。

2、可以确定自己连接到什么类型的云上的命令:netsh p2p pnrp cloud show list

3、命令显示出的 Scope值是3的话是本地连接云,如果Scope是1的话就是全局的云。

4、Windows7还引入了一种新的方式Easy Connect,用于连接到Remote Assistance应用程序的其他用户上。可以共享其桌面。(书没有详细说)

三、PNRP的例子

IP2PService接口

View Code
namespace P2PService
{
    [ServiceContract()]
    interface IP2PService
    {
    
        [OperationContract]
        string GetName();
        [OperationContract(IsOneWay=true)]
        void MessageSend();
    }
}

实现WCF服务接口的类P2PService

View Code
namespace P2PService
{
    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
   public class P2PService:IP2PService
    {
       private Program program;
       private string username;
       public P2PService(Program p,string name)
       {
           this.program = p;
           this.username = name;
       }
        string IP2PService.GetName()
        {
            return username;
        }

        void IP2PService.MessageSend()
        {
            program.SendMessage("topone","service");
        }
    }
}

PeerEntry

View Code

服务端

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.PeerToPeer;
using System.Net.PeerToPeer.Collaboration;
using System.Configuration;
using System.Net;
using System.ServiceModel;
namespace P2PService
{
    public class Program
    {
        private P2PService localService;
        private string serviceUrl;
        private ServiceHost host;
        private PeerName peerName;
        private PeerNameRegistration peerNameRegistration;
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Load();
            //得到对等机
            p.peerName = new PeerName("Peer classifier", PeerNameType.Unsecured);
            p.peerNameRegistration = new PeerNameRegistration(p.peerName, 8383,Cloud.Global);
            p.peerNameRegistration.Comment = "Get pizza here";
            p.peerNameRegistration.Start();
            Console.ReadKey();
        }
        public void Load()
        {
            string port = ConfigurationManager.AppSettings["port"];
            string username = ConfigurationManager.AppSettings["username"];
            string machineName = Environment.MachineName;
            serviceUrl = null;
            Console.WriteLine("本机名字:" + username);
            foreach (IPAddress address in Dns.GetHostAddresses(Dns.GetHostName()))
            {
                if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    serviceUrl = string.Format("net.tcp://{0}:{1}/P2PService", address, port);
                    break;
                }
            }
            if (!string.IsNullOrEmpty(serviceUrl))
            {
                Console.WriteLine("这里了");
            }
            WCFStrat(this, username);

        }
        /// <summary>
        /// 启动WCF服务
        /// </summary>
        /// <param name="p"></param>
        /// <param name="username"></param>
        public void WCFStrat(Program p, string username)
        {
            localService = new P2PService(p, username);
            host = new ServiceHost(localService, new Uri(serviceUrl));
            NetTcpBinding binding = new NetTcpBinding();
            binding.Security.Mode = SecurityMode.None;
            host.AddServiceEndpoint(typeof(IP2PService), binding, serviceUrl);
            try
            {
                host.Open();
            }
            catch (AddressAlreadyInUseException)
            {
                Console.WriteLine("服务启动错误");
            }
        }
        public void SendMessage(string name, string from)
        {
            Console.WriteLine("对等机的名称:" + name + " 从:" + from);
        }
    }
}

 

客户端包含一个连接WCP TCP类型的

View Code
class Program
    {
        static void Main(string[] args)
        {
            PeerName pn = new PeerName("0.Peer classifier");
            PeerNameResolver pnres = new PeerNameResolver();
            //解析对等机
            PeerNameRecordCollection pnrc = pnres.Resolve(pn, Cloud.Global);
            foreach (var p in pnrc)
            {
                Console.WriteLine(p.Comment);
                foreach (IPEndPoint ep in p.EndPointCollection)
                {
                    if (ep.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        string  endpointUrl = string.Format("net.tcp://{0}:{1}/P2PService", ep.Address, ep.Port);
                        NetTcpBinding binding = new NetTcpBinding();
                        binding.Security.Mode = SecurityMode.None;
                        IP2PService serviceProxy = ChannelFactory<IP2PService>.CreateChannel(binding, new EndpointAddress(endpointUrl));
                        Console.WriteLine(serviceProxy.GetName());
                        //serviceProxy.MessageSend();
                        break;
                    }
                }
                Console.ReadKey();
            }

        }
    }

四、代码安全访问性

1、PnrpPermission和PnrpPermissionAtrribute

五、PNM

1、签入和签出,静态类PeerCollaboration

PNM例子(要两台机子)

服务端

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.PeerToPeer.Collaboration;
namespace PNMService
{
    class Program
    {
        static void Main(string[] args)
        {
            PeerCollaboration.SignIn(PeerScope.All);
            //PeerPresenceStatus可以设置对等机的状态 在线或离线等等
           PeerCollaboration.LocalPresenceInfo = new PeerPresenceInfo(PeerPresenceStatus.Online,"测试");
           Console.WriteLine(ContactManager.LocalContact.Nickname);

            Console.ReadKey();

        }
    }
}

客户端

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.PeerToPeer.Collaboration;
namespace PNMClient
{
    class Program
    {
        static void Main(string[] args)
        {
            PeerNearMeCollection peersNearMe = PeerCollaboration.GetPeersNearMe();
           foreach (PeerNearMe peerNearMe in peersNearMe)
           {
               Console.WriteLine(peerNearMe.PeerEndPoints[0].Name);
           }
           Console.ReadKey();
        }
    }
}

 

 

posted on 2013-03-02 20:56  R.Ray  阅读(806)  评论(0)    收藏  举报

导航