MFC get your external ip address

I recently wrote a program in MFC that would monitor your ip address.  This was great but I soon realized if your behind a NAT of some kind you get your internal ip address.  I soon realized a need to know my external ip address.  There is no built in functionality to do this in windows so you have to ping an outside server or website that will tell you what your ip address is.  There are several ways to do this sockets, an http request, or urlmon.  Many people say sockets is the best since you can use any version of windows and create a socket.  The issue is the socket code is extremely long and complicated.  I only need to support windows 2000 and above so I decided using the urlmon way was much simpler and faster.  Here is some code in MFC to hit an outside website which returns your IP address in file that you then parse for the data.

This is in a class with a CString member variable called m_strExternalIp.




m_strExternalIp = _T( "Unavailable" );

try
{    
    /*

        to make the UrlDownloadToFile call you need the following defined

        #include <urlmon.h>

        #pragma comment(lib, "urlmon.lib")

        */

     // holds the url to check and the name of the file to write the data to
    TCHAR url[47] = _T("http://checkip.dyndns.org/Current IP Check.htm");
    TCHAR file[7] = _T("ip.txt");

     // here is the urlmon.dll method call, see note above
    if( URLDownloadToFile( 0, url, file, 0, 0) == S_OK )
    {
        CStdioFile file;

         // open the file for reading
        if( file.Open( _T("ip.txt"), CFile::modeRead | CFile::modeNoTruncate ) )
        {
            file.ReadString( m_strExternalIp );
 
             // file if successful is in format
            // <html><head><title>Current IPCheck</title></head><body>Current IP Address: 174.52.71.72</body></html>
            if( m_strExternalIp.GetLength() > 110 )
            {
                m_strExternalIp = _T( "Unable to access IP check site" );
            }
            else
            {
                m_strExternalIp = m_strExternalIp.Mid( m_strExternalIp.Find( _T(": ") ) + 1, m_strExternalIp.GetLength() - m_strExternalIp.Find( _T("</body>") ) - 1 );
             }

             // always close the file
            file.Close();

        }
    }
    else
    {
        m_strExternalIp = _T( "Unable to access IP check site" );
    }
  }
 catch( CException* ex )
 {
     // write any errors to a log file
    TCHAR   szCause[255];
    CString strFormatted;

    ex->GetErrorMessage(szCause, 255);

    strFormatted = _T("The following error occurred: ");
    strFormatted += szCause;

    CStdioFile file(_T("error_log.txt"), CFile::modeWrite | CFile::modeNoTruncate );

    if( file )
    {
        file.WriteString( strFormatted );
    }

    file.Close();

    delete ex;

}


Read more about the urlmon stuff on MSDN

http://msdn.microsoft.com/en-us/library/ms775123(v=vs.85).aspx

Comments

Anonymous said…
Cool. Thanks!

Popular posts from this blog

String.Replace vs Regex.Replace

C# Form Application in Kiosk Mode/Fullscreen

C# using a transaction with ODBC