How to get local IP Address in Delphi

Many time we need to check for local system IP address where our application is running. And here I have explained several ways to get local IP Address in Delphi. I have used Delphi Tokyo for the examples so some examples may not execute in old Delphi versions.

So lets check the codes...

1. Using Winsock Delphi unit
Winsock Unit is a wrapper to Windows Sockets API. This API is generally used to implement client server applications.

uses
    Winsock;
.......
function GetLocalIP: string;
type
  TaPInAddr = array [0..10] of PInAddr;
  PaPInAddr = ^TaPInAddr;
var
  phe: PHostEnt;
  pptr: PaPInAddr;
  Buffer: array [0..63] of Ansichar;
  i: Integer;
  GInitData: TWSADATA;
begin
  WSAStartup($101, GInitData);
  Result := '';
  GetHostName(Buffer, SizeOf(Buffer));
  phe := GetHostByName(Buffer);
  if phe = nil then
    Exit;
  pptr := PaPInAddr(phe^.h_addr_list);
  i := 0;
  while pptr^[i] <> nil do
  begin
    Result := StrPas(inet_ntoa(pptr^[i]^));
    Inc(i);
  end;
  WSACleanup;
end;

2. Using TIDStack Indy class
TIdStack is an abstract base class so we cannot instantiate it directly.  We have to use the global GStack variable instead.  Call the TIdStack.IncUsage() class
method to ensure GStack is intialized before accessing it.

uses
  IdStack;
.....
function GetIP : String;
begin
  TIdStack.IncUsage;
  try
    Result := GStack.LocalAddress;
  finally
    TIdStack.DecUsage;
  end;
end;

3. Using TIdIpWatch Indy component
TIdIPWatch component is meant for monitoring changes to the machine's active IP in (near) real-time. It stores history of IP Addresses.

We just need to put TIdIPWatch component on a form and call IdIpWatch1.LocalIP function to get local IP Address.

or 

We can create a TIdIPWatch object in a function:
Uses
    IdBaseComponent, IdComponent, IdIPWatch;
.....
function GetLocalIp: string;
var 
   IPW: TIdIPWatch;
begin   
  IpW := TIdIPWatch.Create(nil);
  try
    if IpW.LocalIP <> '' then
      Result := IpW.LocalIP;
  finally
    IpW.Free;
  end;
end;

4. Using JCL
The Jedi Code Library contains a procedure GetIpAddresses that returns current IP address.

uses
    JclSysInfo
.....
procedure GetIpAddresses(Results: TStrings); 

Call procedure GetIPAddresses and pass a TStringlist type variable as parameter in which it will store IP Address.


And here I have also added a function to check if a String is a valid IP Address

function IsWrongIP(ip: string): Boolean; 
var 
  z, i: byte; 
  st: array[1..3] of byte; 
const 
  ziff = ['0'..'9']; 
begin 
  st[1]  := 0; 
  st[2]  := 0; 
  st[3]  := 0; 
  z      := 0; 
  Result := False; 
  for i := 1 to Length(ip) do if ip[i] in ziff then 
  else 
  begin 
    if ip[i] = '.' then 
    begin 
      Inc(z); 
      if z < 4 then st[z] := i 
      else 
      begin 
        IsWrongIP := True; 
        Exit; 
      end; 
    end 
    else 
    begin 
      IsWrongIP := True; 
      Exit; 
    end; 
  end; 
  if (z <> 3) or (st[1] < 2) or (st[3] = Length(ip)) or (st[1] + 2 > st[2]) or 
    (st[2] + 2 > st[3]) or (st[1] > 4) or (st[2] > st[1] + 4) or (st[3] > st[2] + 4) then 
  begin 
    IsWrongIP := True; 
    Exit; 
  end; 
  z := StrToInt(Copy(ip, 1, st[1] - 1)); 
  if (z > 255) or (ip[1] = '0') then 
  begin 
    IsWrongIP := True; 
    Exit; 
  end; 
  z := StrToInt(Copy(ip, st[1] + 1, st[2] - st[1] - 1)); 
  if (z > 255) or ((z <> 0) and (ip[st[1] + 1] = '0')) then 
  begin 
    IsWrongIP := True; 
    Exit; 
  end; 
  z := StrToInt(Copy(ip, st[2] + 1, st[3] - st[2] - 1)); 
  if (z > 255) or ((z <> 0) and (ip[st[2] + 1] = '0')) then 
  begin 
    IsWrongIP := True; 
    Exit; 
  end; 
  z := StrToInt(Copy(ip, st[3] + 1, Length(ip) - st[3])); 
  if (z > 255) or ((z <> 0) and (ip[st[3] + 1] = '0')) then 
  begin 
    IsWrongIP := True; 
    Exit; 
  end; 
end;

Comments

  1. How can i able send message from one ip address and
    receive in another ip address?
    With delphi application used in two ip address.

    ReplyDelete
    Replies
    1. Typically, IP communication is performed through a single connected, persistent socket... one side is the client (the one initiating the connection) and the other being the server (the one listening for a connection). Nothing prevents you from opening multiple connections where you can segment traffic.

      For example, if you have two computers: WorkPC and HomePC, this can be done as simply as having both WorkPC and HomePC open listening connections (server), and both spawning initiator connections (client). In this instance, maybe you jot down on a little piece of paper the IP and Port your HomePC is listening on before going to work, and connecting to it after getting to the office. The, direct your HomePC that, upon receiving a connection and some sort of credentials you want to use, to initiate a connection with the awaiting IP/Port on your WorkPC. Since both are acting as servers, and both are acting as clients, you can have your code way "whenever I get a packet on my server socket, send a response from my client socket."

      Delete
  2. Thanks, but is it possible to get more than one local IP addresses?

    ReplyDelete
    Replies
    1. Of course it is, if you have multiple NIC's

      Delete

Post a Comment

Popular posts from this blog

ShellExecute in Delphi

How to send Email in Delphi?

Drawing Shapes in Delphi