What is my IP address?

Posted by on in Blogs

There are many situation when it would handy to know the IP address of a device where our app is running. Maybe you want to identify who is running your app? By IP address it is also possible to calculate the approximate location of a device. If you connect to Internet through a router, there are big chances that it implements "Network Address Translation" (NAT), to make it harder for remote machines to establish a direct connection to a machine within a local network.

Recently I have come across a very simple and useful REST API that makes it possible to get the IP address and the geographical location of a client that invokes it. In this way we could find out under which IP address the Internet "sees" us.

If you send an HTTP GET request to http://ip-api.com/json, you will receive a JSON document with information about your IP address, longitude and latitude, country, city, zip code, ISP provider name, timezone and region.

In order to make this service easily accessible in code I have put together a little Delphi "TMyIP" class that provides one class function "GetInfo" that takes "TIPInfo" record "out" parameter and returns a boolean value that indicates if the parameter contains valid information. The actual HTTP GET request is made using the native "THTTPClient" class from "System.Net.HttpClient" unit. The JSON processing is done using "TJSONTextReader" class.

Below is the full source code of the "uMyIP" unit that contains the "TMyIP" class.


unit uMyIP;

interface

type
  TIPInfo = record
    status: string;
    aAs: string;
    city: string;
    country: string;
    countyCode: string;
    Isp: string;
    lat: double;
    lon: double;
    org: string;
    IPAddress: string;
    region: string;
    regionName: string;
    timezone: string;
    zip: string;
  end;

  TMyIP = class
  public
    class function GetInfo(out info: TIPInfo): boolean;
  end;

implementation

uses
  System.SysUtils,
  System.Classes,
  System.JSON.Readers,
  System.JSON.Types,
  System.Net.HttpClient;

const
  IP_API_JSON_URL = 'http://ip-api.com/json';

{ TMyIP }

class function TMyIP.GetInfo(out info: TIPInfo): boolean;
var c: THTTPClient; json: string; sr: TStringReader; jtr: TJsonTextReader;
  resp: IHTTPResponse;
begin
  Result := False;
  c := THTTPClient.Create;
  try
    try
      resp := c.Get(IP_API_JSON_URL);
      json := resp.ContentAsString;
    except
      exit;
    end;
  finally
    c.Free;
  end;

  sr := TStringReader.Create(json);
  try
    jtr := TJsonTextReader.Create(sr);
    try
      while jtr.Read do
      begin
        if jtr.TokenType = TJsonToken.PropertyName then
        begin
          if jtr.Value.ToString = 'status' then
          begin
            jtr.Read;
            info.status := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'as' then
          begin
            jtr.Read;
            info.aAs := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'city' then
          begin
            jtr.Read;
            info.city := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'country' then
          begin
            jtr.Read;
            info.country := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'countyCode' then
          begin
            jtr.Read;
            info.countyCode := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'isp' then
          begin
            jtr.Read;
            info.isp := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'lat' then
          begin
            jtr.Read;
            info.lat := jtr.Value.AsExtended;
          end

          else if jtr.Value.ToString = 'lon' then
          begin
            jtr.Read;
            info.lon := jtr.Value.AsExtended;
          end

          else if jtr.Value.ToString = 'org' then
          begin
            jtr.Read;
            info.org := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'query' then
          begin
            jtr.Read;
            info.IPAddress := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'region' then
          begin
            jtr.Read;
            info.region := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'regionName' then
          begin
            jtr.Read;
            info.regionName := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'timezone' then
          begin
            jtr.Read;
            info.timezone := jtr.Value.AsString;
          end

          else if jtr.Value.ToString = 'zip' then
          begin
            jtr.Read;
            info.zip := jtr.Value.AsString;
          end

        end;
      end
    finally
      jtr.Free;
    end;
  finally
    sr.Free;
  end;

  Result := info.status = 'success';
end;

end.

Let's quickly test this class. Start Delphi and create a new "Multi-Device Application" project. Choose "Blank Application" template and save the main form as "uFormMyIP" and the whole project as "MyIP". You can optionally change the "Name" property of the form to "FormMyIP". Add a new unit to the project and save it as "uMyIP". Copy the above code, select the source code of the empty unit and paste the code to replace the entire content. Now add the new "uMyIP" unit to the uses clause of the form. Drop a button on the form and align it to "Top". Change its "Text" property to "Check IP". Drop "TListView" control onto the form, align it to "Client" and change its "Name" property to "lstvwInfo". Double-click on the button and add the following code to the "OnClick" event handler to invoke the "TMyIP.GetInfo" and display the data in the list view.


uses uMyIP;

procedure TFormMyIP.btnCheckIPClick(Sender: TObject);

  procedure AddItem(txt, det: string);
  var item: TListViewItem;
  begin
    item := lstvwInfo.Items.Add;
    item.Text := txt;
    item.Detail := det;
  end;

var info: TIPInfo; item: TListViewItem;
begin
  if TMyIP.GetInfo(info) then
  begin
    lstvwInfo.BeginUpdate;
    try
      lstvwInfo.Items.Clear;
      AddItem(info.IPAddress, 'IP address');
      AddItem(info.city, 'City');
      AddItem(info.country, 'Country');
      AddItem(info.timezone, 'Timezone');
      AddItem(info.lat.ToString, 'Latitude');
      AddItem(info.lon.ToString, 'Longitude');
    finally
      lstvwInfo.EndUpdate;
    end;
  end
  else
    ShowMessage('Failed');
end;

Save all and run the project. When you click on the button you should see how the world sees You!

The complete source code of this simple demo can be downloaded from here. Enjoy!



About
Gold User, Rank: 9, Points: 364
Crazy about Delphi Programming!

Comments

  • ralf M52700
    ralf M52700 Friday, 17 November 2017

    Hello Pawel,

    is it possible to get the source code from the json to "make it round" how it works?

    Thank you.

    Ralph

  • Paweł Głowacki
    Paweł Głowacki Tuesday, 21 November 2017

    Hi Ralph,
    Could you explain what do you mean by "make it round"? All the source is provided.
    best regards,
    Paweł

  • Please login first in order for you to submit comments
  • Page :
  • 1

Check out more tips and tricks in this development video: