Get IP Address that your PC presents to the world (C#)

May 4, 2007 @ 9:10 pm by walter — Filed under: .NET

Here’s a question, posed on the Universal Thread - how do you find out the IP address that your PC presents to the world?

This is something that your PC cannot answer for itself. For example, my PC currently is aware of at least three IP addresses - 127.0.01 is the “loopback” or “localhost” address which is never seen outside of the PC (This is quite standard, pretty much every computer with TCP/IP ability will use this address). I’ve also got the IP address my PC’s wireless ethernet card is using, currently 192.168.33.90 (but this could change, it is assigned by my router via DHCP). Finally there is also 192.168.84.6 which is the current address of my VPN link into the office. But none of these are the IP address that the world sees.

What the world sees - for instance a web server or mail server - is actually the IP address of my router’s external interface. In my case something like 203.x.y.z (again, the x,y,z change). To capture this, requires something on the other side of my router that my PC can query.

This is pretty easy as long as you have an external web server. For example, here’s an ASP.NET page (call it getip.aspx) that returns the requesting computer’s IP address:

< %@ Page language="c#"  %>< % 
    Response.Write( Request.UserHostAddress );
%>

Or if you want a PHP version instead, here’s getip.php:

< ?php
 print $_SERVER['REMOTE_ADDR'];
?>

You can test these simply by typing the address of into a web browser. And in fact there are sites such as http://checkip.dyndns.org/ which will give you the same information. But what if you want this value in a program. In .NET v2 it’s pretty easy. Here’s my getip.cs

using System;
using System.Net;

public class GetIpApp
{
   static void Main( string[] args)
   {
      if( args.Length&lt;1 ) {
         Console.WriteLine( "Usage: getip <url>" );
         return;
      }
      WebClient client = new WebClient();
      
      try {
         string strIpAddress = client.DownloadString( args[0] );
         Console.WriteLine( "IP Address is: {0}", strIpAddress );
      }
      catch( Exception ex ) {
         Console.WriteLine( ex.ToString() );
      }
   }
}</url>

Use this test program simply by passing a URL as the first argument from a windows command line, like so

C:\\work\\getip>getip http://your.server.goes.here/getip.php
IP Address is: aaa.bbb.ccc.ddd

C:\\work\\getip>

Now come a couple of things to tidy up.

Converting the IP address from a string to other forms, error handling and so on I leave up to you. You might want to look at the method System.Net.IPAddress.Parse() for instance.

The web pages above actually return invalid HTML. To play nicely by the rules you should really change the HTTP content type to text/plain (or return valid html and your client program needs to do a bit more parsing). This makes the C# version:

< %@ Page language="c#"  %>< % 
    Response.ContentType = "text/plain"; 
    Response.Write( Request.UserHostAddress );
%>

and PHP:
< ?php
 header( 'text/plain' );
 print $_SERVER['REMOTE_ADDR'];
?>

Finally, I should mention that even with all this effort, the IP address the web server gets may not be the IP address you desire. For example, your ISP might be operating a caching proxy server and so the address of that is captured instead. The easiest way around this is to connect to the web server using a non-standard port (not port 80) which the proxy server will not intercept.

If this is not possible - perhaps because your web server is provided by someone else and you cannot get it to listen on any other ports, or your firewall is restricting what external ports you can attach to, then the technique used depends on the particular proxy server. Some proxy servers are deliberately anonymous and there simply is no way at all. You can find a small discussion about this on the What is My IP address web site.

(Note the code samples in this post may be reformatted slightly by the blog software, so don’t trust an exact copy and paste!)