C# P2P通信之UPNP操作类的实现

主要依托于COM互操作来实现

添加COM引用 使用UPNP 1.0类型库 npnp.dll

主要对UPNP操作做了一个封装

1.自定义类型支持

 

public enum ProtocolType
{
    UDP,
    TCP
}

/// <summary>
/// 端口映射信息
/// </summary>
public class PortMappingInfo
{
    
public string InternalIP;
    
public int ExternalPort;
    
public int InternalPort;
    
public ProtocolType type;
    
public string Description;
    
public PortMappingInfo(string internalIP, int externalPort, int internalPort, ProtocolType type, string description)
    {
        
this.InternalIP = internalIP;
        
this.ExternalPort = externalPort;
        
this.InternalPort = internalPort;
        
this.type = type;
        
this.Description = description;
    }
}

 

2.UPnP类实现

 

using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Net;
using System.Xml;
using System.IO;
using System.Net.Sockets;
using NATUPNPLib;

namespace Network
{
    
public sealed class UPnPNat
    {
        
private UPnPNATClass _uPnPNAT;
        
        
public UPnPNat()
        {
            
try
            {
                UPnPNATClass nat 
= new UPnPNATClass();
                
//if (nat.NATEventManager != null && nat.StaticPortMappingCollection != null)
                    _uPnPNAT = nat;
            }
            
catch{}

            
if(_uPnPNAT==null)
                
throw new NotSupportedException("没有可配置的UPNP NAT活动");
        }
        
/// <summary>
        
/// 增加端口映射
        
/// </summary>
        
/// <param name="ExternalPort">外部端口(路由器 NAT设备打开的端口)</param>
        
/// <param name="InternalPort">内部端口 本机的端口</param>
        
/// <param name="type">协议类型 UDP或TCP</param>
        
/// <param name="InternalClient">内网IP地址或主机名</param>
        
/// <param name="enable">是否启用</param>
        
/// <param name="description">描述信息</param>
        public void AddStaticPortMapping(int ExternalPort,int InternalPort,ProtocolType type,string InternalClient,bool enable,string description)
        {
            _uPnPNAT.StaticPortMappingCollection.Add(ExternalPort, type.ToString().ToUpper(), InternalPort, InternalClient, enable, description);
        }
        
/// <summary>
        
/// 移除端口映射
        
/// </summary>
        
/// <param name="ExternalPort">外部端口号</param>
        
/// <param name="type">协议类型</param>
        public void RemoveStaticPortMapping(int ExternalPort,ProtocolType type)
        {
            _uPnPNAT.StaticPortMappingCollection.Remove(ExternalPort, type.ToString().ToUpper());
        }
        
public UPnPNATClass UPnPNAT
        {
            
get { return _uPnPNAT; }
        }

        
/// <summary>
        
/// 获取端口映射信息
        
/// </summary>
        public PortMappingInfo[] PortMappingsInfos
        {
            
get
            {
                System.Collections.ArrayList portMappings 
= new ArrayList();
                
int count = _uPnPNAT.StaticPortMappingCollection.Count;
                IEnumerator enumerator 
= _uPnPNAT.StaticPortMappingCollection.GetEnumerator();
                enumerator.Reset();
                
for (int i = 0; i < count; i++)
                {
                    IStaticPortMapping mapping 
= null;
                    
try
                    {
                        
if(enumerator.MoveNext())
                            mapping
=(IStaticPortMapping)enumerator.Current;
                    }
                    
catch { }
                    
if (mapping != null)
                        portMappings.Add(
new PortMappingInfo(mapping.InternalClient, mapping.ExternalPort, mapping.InternalPort, mapping.Protocol == "TCP" ? ProtocolType.TCP : ProtocolType.UDP, mapping.Description));
                }
                PortMappingInfo[] portMappingInfos 
= new PortMappingInfo[portMappings.Count];
                portMappings.CopyTo(portMappingInfos);
                
return portMappingInfos;
            }
        }
        
    }

    
}

 

使用NAT设备(路由器)的端口映射功能是实现P2P的一种重要方式 在UPNP开启的情况下把一台内网计算机直接暴露到公网上

posted on 2011-03-13 07:51  狐狸狡猾不  阅读(5560)  评论(1编辑  收藏  举报

导航



Powered by: 博客园 copyright © 2009-2012 狐狸狡猾不