最近在研究p2p,通过网上的例子也实现了udp方式的穿透。
同时也在网上看到UPnP也可以实现NAT的穿透,但是还不了解其原理。
刚刚在配置路由器的时候,发现Baidu Hi在路由器的UPnP列表中存在端口映射,不知道这个是否是用来NAT穿透的?了解UPnP的兄弟谈谈看法 :)
同时也在网上看到UPnP也可以实现NAT的穿透,但是还不了解其原理。
刚刚在配置路由器的时候,发现Baidu Hi在路由器的UPnP列表中存在端口映射,不知道这个是否是用来NAT穿透的?了解UPnP的兄弟谈谈看法 :)
解决方案 »
- 如何在CSliderCtrl上添加标记
- 如何完全删除界面上已有的控件及其对应的处理函数??
- 为Microsoft MPEG-4 Video Codec V1 创建Filter,确始终创建不成功怎么回事???
- 想在vc.net里使用CString/String,尝试了不下4种方法,均失败
- 如何重载ATL类厂的CreateInstance函数。
- 使用双缓冲绘图时出现错误!
- 兄弟们,帮俺看看这个多播程序哪儿出错了?我甚至都怀疑集线器有问题了。
- 帮我看看哪错了?
- 如何通过写程序共享一个文件夹?
- 做控件等图标,和框架图形的好工具---------ActiveSkin
- 这是什么错误?
- 我想在sdi程序中的view中创建一个chtmlview 但是一调用create方法就内存错误 什么情况?
这下问题又来了:NAT是为解决IP地址不足而引入的;UPNP可好,反NAT之道而行之。试问:假如在一个公共网关下有多个UPNP,它们都能够保证这种映射关系成功吗?又或是在这之间又虚拟了一个NAT出来解决冲突问题?
如果不支持,再使用UDP打洞这样的穿透
效果是一样的
#include <WinSock2.h>
#include "UPnpError.h"class CUPnpNat
{
public:
CUPnpNat(void);
~CUPnpNat(void); enum {SEARCH_TIMEOUT_MS = 15000,
DEF_ACTION_TIMEOUT_MS = 9000}; void SetBindAddress(LPCTSTR lpszBindAddress){m_strBindAddress = lpszBindAddress;}
void SetActionTimeout(int iActionTimeoutMs = DEF_ACTION_TIMEOUT_MS){m_iActionTimeoutMs = iActionTimeoutMs;}
int GetActionTimeout(){return m_iActionTimeoutMs;}
HRESULT SearchDevice(BOOL bUseDefaultGateway = TRUE);
HRESULT AddPortMapping(LPCTSTR lpszRemoteHost,
USHORT usExternalPort, LPCTSTR lpszPortMappingProtocol,
USHORT usInternalPort, LPCTSTR lpszInternalClient,
LPCTSTR lpszPortMappingDescription = NULL,
BOOL bPortMappingEnabled = TRUE,
ULONG ulPortMappingLeaseDuration = 0); HRESULT DeletePortMapping(LPCTSTR lpszRemoteHost,
USHORT usExternalPort,
LPCTSTR lpszPortMappingProtocol);
HRESULT GetSpecificPortMappingEntry(LPCTSTR lpszRemoteHost, //[in]
USHORT usExternalPort, //[in]
LPCTSTR lpszPortMappingProtocol, //[in]
USHORT *pusInternalPort, //[out]
CString *pstrInternalClient, //[out]
bool *pbEnable, //[out]
CString *pstrDescription, //[out]
ULONG *pulPortMappingLeaseDuration); //[out]
HRESULT GetGenericPortMappingEntry(USHORT usIndex, //[in]
CString *pstrRemoteHost, //[out]
USHORT *pusExternalPort, //[out]
CString *pstrProtocol, //[out]
USHORT *pusInternalPort, //[out]
CString *pstrInternalClient, //[out]
bool *pbEnable, //[out]
CString *pstrDescription); //[out] DWORD GetLastActionErrorCode(){return m_dwLastErrorCode;}protected:
void SetLastActionErrorCode(DWORD dwLastErrorCode){m_dwLastErrorCode = dwLastErrorCode;} HRESULT SOAP_action(CString addr, UINT16 port, const CString request, CString &response);
int SSDP_sendRequest(SOCKET s, UINT32 ip, UINT16 port, const CString& request); bool InternalSearch(int version, BOOL bUseDefaultGateway = FALSE);
bool GetDescription();
CString GetProperty(const CString& name, CString& response);
bool isComplete() const { return !m_controlurl.IsEmpty(); }
bool Valid()const{return (/*!m_name.IsEmpty()&&*/!m_description.IsEmpty());} HRESULT InvokeCommand(const CString& name, const CString& args, CString &strResponse); static BOOL IsLengthedHttpPacketComplete(const char *packet, int len);
protected:
CString m_strBindAddress;
int m_iActionTimeoutMs; DWORD m_dwLastErrorCode; BOOL m_isSearched; int m_version;
CString m_devicename;
CString m_name;
CString m_description;
CString m_baseurl;
CString m_controlurl;
CString m_friendlyname;
CString m_modelname;};
#include ".\upnpnat.h"
#include "IpHlpApi.h"
#pragma comment (lib, "IpHlpApi.lib")
//#define NUMBEROFDEVICES 2
//static const CString s_devices[][2] = {{_T("WANIPConnection"), _T("service")},
// {_T("WANPPPConnection"), _T("service")}};#define UPNPPORTMAP0 _T("WANIPConnection")
#define UPNPPORTMAP1 _T("WANPPPConnection")
static const ULONG UPNPADDR = 0xFAFFFFEF;
static const int UPNPPORT = 1900;
static const CString URNPREFIX = _T("urn:schemas-upnp-org:");//////////////////////////////////////////////////////////////////////////
//extern const CString getString(int i);
extern const CString GetArgString(const CString& name, const CString& value);
extern const CString GetArgString(const CString& name, int value);
extern bool parseHTTPResponse(const CString& response, CString& result);
extern const CString getProperty(const CString& all, const CString& name);const CString getString(int i)
{
CString s; s.Format(_T("%d"), i); return s;
}const CString GetArgString(const CString& name, const CString& value)
{
return _T("<") + name + _T(">") + value + _T("</") + name + _T(">");
}const CString GetArgString(const CString& name, int value)
{
return _T("<") + name + _T(">") + getString(value) + _T("</") + name + _T(">");
}bool parseHTTPResponse(const CString& response, CString& result)
{
int pos = 0; CString status = response.Tokenize(_T("\r\n"), pos); result = response;
result.Delete(0, pos); pos = 0;
status.Tokenize(_T(" "), pos);
status = status.Tokenize(_T(" "), pos);
if (status.IsEmpty() || status[0]!='2') return false;
return true;
}