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;
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;
Excelent post. Thak you
ReplyDeleteHow can i able send message from one ip address and
ReplyDeletereceive in another ip address?
With delphi application used in two ip address.
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.
DeleteFor 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."
Thanks, but is it possible to get more than one local IP addresses?
ReplyDeleteOf course it is, if you have multiple NIC's
DeleteA good idea
ReplyDelete