What is my IP address?
What is my IP address?
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!