I wanted to learn socket programming, so I made a nice little web server that uses IO completion ports and all that good stuff. When I forward the port manually from within the my router's settings, the server runs fine. I recently tried to get it to work with uPnP, but had no luck.
I tried connecting to the server from outside my home network, but couldn't get a response.
I checked that:
1) uPnP is enabled in the router's settings
2) I am not receiving any errors from my code
This is the code for the wrapper that I made:
mappedport.h
#ifndef INC_MAPPEDPORT_H#define INC_MAPPEDPORT_H#pragma comment (lib, "ws2_32.lib")#include <winsock2.h>#include <ws2tcpip.h>#include <Natupnp.h>#include <Windows.h>class MappedPort{private: HRESULT hr; wchar_t protocol_[4]; long lport_; bool initialized_; bool mapped_; IUPnPNAT *uPnP; IStaticPortMapping *spmOut; IStaticPortMappingCollection *spmCol; bool Initialize();public: MappedPort(); MappedPort(long lPort, wchar_t *protocol /* "TCP" or "UDP" */, wchar_t *description); ~MappedPort(); bool Map(long lPort, wchar_t *protocol /* "TCP" or "UDP" */, wchar_t *description); bool Unmap(); bool IsMapped();};#endif /* INC_MAPPEDPORT_H */
mappedport.cpp
#include "mappedport.h"MappedPort::MappedPort(){ Initialize();}MappedPort::MappedPort(long lPort, wchar_t *protocol, wchar_t *description){ if(Initialize()) mapped_ = Map(lPort, protocol, description);}bool MappedPort::Initialize(){ lport_ = 0; mapped_ = false; initialized_ = false; hr = 0; uPnP = NULL; spmOut = NULL; spmCol = NULL; if(CoInitialize(NULL) == S_OK) { hr = CoCreateInstance(__uuidof(UPnPNAT), NULL, CLSCTX_ALL, __uuidof(IUPnPNAT), (void **)&uPnP); if(hr == S_OK && uPnP != NULL) { hr = uPnP->get_StaticPortMappingCollection(&spmCol); if(hr == S_OK && spmCol != NULL) { initialized_ = true; } } } return initialized_;}MappedPort::~MappedPort(){ if(mapped_) this->Unmap(); if(uPnP) uPnP->Release(); if(spmCol) spmCol->Release(); if(spmOut) spmOut->Release(); if(initialized_) CoUninitialize();}bool MappedPort::Map(long lPort, wchar_t *protocol, wchar_t *description){ WSADATA wsaData; char hostname[256]; PHOSTENT hostinfo; wchar_t ip[16]; lport_ = lPort; wcscpy_s(protocol_, 4, protocol); if((initialized_ == true) && (mapped_ == false)) { spmCol->Remove(lport_, protocol_); if(WSAStartup(MAKEWORD(2,2), &wsaData) == 0) { if(gethostname(hostname, sizeof(hostname)) == 0) { hostinfo = gethostbyname(hostname); if(hostinfo != NULL) { if(InetNtopW(AF_INET, (struct in_addr*)*hostinfo->h_addr_list, ip, sizeof(ip)) != NULL) { if(spmCol->Add(lPort, protocol, lPort, ip, TRUE, description, &spmOut) == S_OK) { mapped_ = true; } } } } WSACleanup(); } } return mapped_;}bool MappedPort::Unmap(){ return (spmCol->Remove(lport_, protocol_) == S_OK);}bool MappedPort::IsMapped(){ return mapped_;}
If someone could point out any obvious errors that I am making here, it would be greatly appreciated.
bonus: if you can fix it, you can keep it =D
thanks
[Edited by - CPPNick on August 30, 2010 8:46:13 AM]