织梦CMS - 轻松建站从此开始!

罗索

UPNP自动端口映射的实现

落鹤生 发布于 2012-03-16 13:45 点击:次 
我就是看到BitComet的这个功能才学着自己也做一个。因为路由器实现了UPNP的标准接口了,就可以通过upnp来做到编程来做端口映射,免得去找网管了^_^,就是找了他也不一定给你弄呵呵。
TAG:

UPNP是微软定义的一个网络标准,大概是通过网络发送xml定义的数据实现控制网络上的设备等。感兴趣的可以自己到 UPnP™ Forum (http://www.upnp.org/)上下载资料,或者网上搜索一下了。

端口映射: 就是把内网机器的网络端口映射的外部网络的相应端口上,这很多路由器都支持这样的功能。这样人家访问外网ip相应端口时就可以跳转到内网来。很多网络下载 工具都实现这样的功能的,这样人家从外部就可以连接到你内部的机器,便于网络操作,像BitComet,PPstream,迅雷等。

我就是看到BitComet的这个功能才学着自己也做一个。因为路由器实现了UPNP的标准接口了,就可以通过upnp来做到编程来做端口映射,免得去找网管了^_^,就是找了他也不一定给你弄呵呵。

参考资料:

微软的UPnP APIs:http://msdn2.microsoft.com/en-us/library/aa382303.aspx

UPNP标准 设备Internet Gateway Device (IGD) V 1.0 http://www.upnp.org/standardizeddcps/igd.asp

另外如果想实现UPNP的服务端的,好像也有Intel的 UPNP SDK库可以用的。网上也有人很多人写了自动端口映射的程序,我就找到一个使用 socket和 自己处理xml文件的方法实现的。不过我觉得微软有API了用起来也很简单的,不用自己处理那些东西,所以就把msdn上面的实例代码copy一个过来 了,改了一下,还真可以。

大概流程就是:

InternetGatewayDevice -》WANDevice-》WANConnectionDevice

-》WANIPConnection或者 WANPPPConnection,WANIPConnection的 DeletePortMapping,AddPortMapping,GetGenericPortMappingEntry,GetExternalIPAddress 等方法就可以用来做端口映射了。

这是两个实例图:

 

 

 

 

注意在windows的防火墙里面开放 “UPNP框架” 相应的端口UPNP才能正常工作,因为它是通过网络来进行的。

 

 

程序的运行效果如图,我在自己的机器上可以正常显示端口映射,并且进行删除,添加等操作了。发现有的人用PPsteam,迅雷啊等,那些程序都添加了端口映射了。不知道我把他们的映射删了,我的网络会不会快点,哈哈

 

 

 

一些关键代码:

case IDC_START:
    {
     BSTR bstrTypeURI = NULL;
     bstrTypeURI =    SysAllocString(L"urn:schemas-upnp-org:device:InternetGatewayDevice:1");
     IUPnPDevice * internetGatewayDevice =NULL;
     if (FindUPnPDevice(bstrTypeURI,&internetGatewayDevice))
     {
      char devicename[256];
      if (GetDeviceFriendlyName(internetGatewayDevice,devicename))
      {
       hwndTreeView = GetDlgItem(hDlg,IDC_TREE1);
       AddItemToTree(hwndTreeView, devicename, 1);
      }
      SysFreeString(bstrTypeURI);
      bstrTypeURI = SysAllocString(L"urn:schemas-upnp-org:device:WANDevice:1");
      IUPnPDevice * wanDevice =NULL;
      if (GetChildDevice(internetGatewayDevice ,bstrTypeURI ,&wanDevice))
      {
       if (GetDeviceFriendlyName(wanDevice,devicename))
       {
        hwndTreeView = GetDlgItem(hDlg,IDC_TREE1);
        AddItemToTree(hwndTreeView, devicename, 2);
       }
       SysFreeString(bstrTypeURI);
       bstrTypeURI = SysAllocString(L"urn:schemas-upnp-org:device:WANConnectionDevice:1");
       IUPnPDevice * wanConnectionDevice =NULL;
       if (GetChildDevice(wanDevice ,bstrTypeURI ,&wanConnectionDevice))
       {
        if (GetDeviceFriendlyName(wanConnectionDevice,devicename))
        {
         hwndTreeView = GetDlgItem(hDlg,IDC_TREE1);
         AddItemToTree(hwndTreeView, devicename, 3);
        }

        SysFreeString(bstrTypeURI);
        bstrTypeURI = SysAllocString(L"urn:schemas-upnp-org:service:WANIPConnection:1");
        IUPnPService * WANIPConnection =NULL;
        if (GetService(wanConnectionDevice ,bstrTypeURI ,&WANIPConnection))
        {

         hwndTreeView = GetDlgItem(hDlg,IDC_TREE1);
         AddItemToTree(hwndTreeView, "WANIPConnection", 4);

        }
        if (WANIPConnection)
        {  
                    
                                char IPAddress[64];
         if (InvokeGetExternalIPAddress(WANIPConnection,IPAddress))
         {
             hwndTreeView = GetDlgItem(hDlg,IDC_TREE1);
                            AddItemToTree(hwndTreeView, IPAddress, 4);
         }

         hwndTreeView = GetDlgItem(hDlg,IDC_TREE1);
                       AddItemToTree(hwndTreeView, "RemoteHost,ExternalPort

,PortMappingProtocol,InternalPort,InternalClient,PortMappingEnabled

,PortMappingDescription,PortMappingLeaseDuration", 4);
                               
                                char PortMapping[256];
         int i =0;
                         while(InvokeGetGenericPortMappingEntry(WANIPConnection,i,PortMapping))
         {
             hwndTreeView = GetDlgItem(hDlg,IDC_TREE1);
                            AddItemToTree(hwndTreeView, PortMapping, 4);
          i ++;
         }


         WANIPConnection->Release();
        }
        SysFreeString(bstrTypeURI);
        bstrTypeURI = SysAllocString(L"urn:schemas-upnp-org:service:WANPPPConnection:1");
        IUPnPService * WANPPPConnection =NULL;
        if (GetService(wanConnectionDevice ,bstrTypeURI ,&WANPPPConnection))
        {

         hwndTreeView = GetDlgItem(hDlg,IDC_TREE1);
         AddItemToTree(hwndTreeView, "WANPPPConnection", 4);

        }
        if (WANPPPConnection)
        {
         WANPPPConnection->Release();
        }
       }
       if (wanConnectionDevice)
       {
        wanConnectionDevice->Release();
       }

      }
      if (wanDevice)
      {
       wanDevice->Release();
      }

     }
     SysFreeString(bstrTypeURI);
     if (internetGatewayDevice)
     {
      internetGatewayDevice->Release();
     }
    }

    break;

============

不过不知道为什么,端口映射成功后还是没办法从外面连接到里面的ip

(widebright)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201203/15839.html]
本文出处:百度博客 作者:widebright 原文
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
相关文章
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容