Get the machine's IP-address

Back Up Next

Author: Eric Aling
Accessed:
Download: Download PBWS.ZIP ( pbws.zip, 27 Kb )

Lately, I've got several requests for finding out how to get the current PC's IP-address. Well, it took me quite some time and probably, it doesn't work on every machine. In many cases, the IP-address is stored in a special netwerk file, such as NET.CFG but that's pretty static. These days, IP-address are given from DHCP servers so to get it from an ascii file isn't an option anymore. We searching for a more unified method. Well, all the TCP/IP traffic is done via the WinSock DLL ( at least, that's the most important one ). This DLL provides many TCP/IP functions. Each machine is called a host and you can get the hostname with a special function call...gethostname(). Now, if this function succeeds, we can get the IP-address, related to this hostname. If the gethostname fails, I'm out of luck, that means, I haven't found another way to get the IP-address yet.

Second part is getting the IP-address related to the hostname. For this, another special function is provided by the WinSock dll. To do this, we use the gethostbyname() function, with the hostname as argument. This function returns a pointer to a structure and you probably know that with PowerBuilder, we cannot do a lot more with this pointer. I've tried to manipulate the pointer in Powerbuilder, believe me I tried and tried and tried but no way. We need a DLL, or a C++ class to work with this pointer. Luckily, it's is PowerSoft themselves who are providing this DLL ( and even the C-source ). It comes with one of their application galery examples, namely the FTP example. Basically, what this function does it mapping elements of the structure to PowerBuilder variables.

Now, before we can even use WinSock functions, we must have a valid session. This session is created with the WinSock wsastartup() function. This function uses a structure, the WSAdata structure. It's defined like this:

$PBExportHeader$s_wsadata.srs
global type s_wsadata from structure
unsignedinteger version
unsignedinteger highversion
character description[257]
character systemstatus[129]
unsignedinteger maxsockets
unsignedinteger maxupddg
string vendorinfo
end type

So, create this structure globally and name it s_wsadata. Let's walk through the code:

/* First, declare all the needed variables */
s_wsadata	l_WSAData
string		ls_HostName = space(128)
string		ls_IpAddress
int		li_version = 257
blob{4} 	lb_hostaddress 
/* Then, create a session, based on the winsock version. This version number consists of two part, a major and minor release number, both represented in a byte. So, version 1.1 gives us an integer version of 257 ( 256 + 1 ) */
IF wsastartup ( li_version, l_WSAData ) = 0 THEN
/* the wsadata structure contains several information. The description element tells us the winsock version */
	messagebox("Winsock Version", l_WSAData.description )
/* Now, let's find out what the hostname is of the current machine we're working on */
	IF gethostname ( ls_HostName, len(ls_HostName) ) < 0 THEN
		messagebox("GetHostName",WSAGetLastError())
	ELSE
/* With the hostname, call the DLL function and map the IP-address pointers to a PB blob variable, with a length of 4 bytes. This is done because the internal structure contains 4 pointers, each pointer point to one of the parts of the IP-address. An IP-address namely, consists of 4 bytes */
		Messagebox("Hostname", ls_HostName)
		GetHost(ls_HostName, lb_HostAddress)
/* Convert the pointers to scalars, and concatenate them to one string, the IP-address */
		ls_IpAddress = string(asc(string(blobmid(lb_HostAddress,1,1))),"000") + "."
		ls_IpAddress += string(asc(string(blobmid(lb_HostAddress,2,1))),"000") + "."
		ls_IpAddress += string(asc(string(blobmid(lb_HostAddress,3,1))),"000") + "."
		ls_IpAddress += string(asc(string(blobmid(lb_HostAddress,4,1))),"000")
		Messagebox("Ip Address", ls_IpAddress )
	END IF
/* We're finished, clean up the mess we made */
	WSACleanup()
ELSE
	messagebox("GetHostName",WSAGetLastError())
END IF 

 

Right. Now, to get this thing on the road, you need some external functions. For 16bit applications:

function int WSAStartup ( int lVersionRequested, ref s_WSAData w ) library "winsock.dll" 
function int WSACleanup () library "winsock.dll" 
function int WSAGetLastError () library "winsock.dll" 
function int gethostname ( ref string name, int namelen ) library "winsock.dll"
function string GetHost(string lpszhost, ref blob lpszaddress ) library "pbws.dll" 

And for 32bit applications:

function int WSAStartup( uint UIVersionRequested, ref s_WSAData lpWSAData ) library "wsock32.dll"
function int WSACleanup() library "wsock32.dll"
function int WSAGetLastError ( ) library "wsock32.dll"
function int gethostname ( ref string name, int namelen ) library "wsock32.dll"
function string GetHost(string lpszhost, ref blob lpszaddress ) library "pbws32.dll" 

The pbws.dll and pbws32.dll are the PS DLLs I was talking about. Click on the folder image to download them, very small, including the source code. That should do it. For more information about WinSock programming, see the WinAPI helpfiles and MSDN ( which is alos available on Microsoft's website.

Good Luck!

Back Up Next