Recent

Author Topic: Get IP address in Lazarus Pascal  (Read 464 times)

shonay

  • Full Member
  • ***
  • Posts: 165
Get IP address in Lazarus Pascal
« on: June 20, 2019, 05:06:00 pm »
HI i want to ask u a question ,

Hw do i get the IP address in Pascal , i followed this http://www.cplusplus.com/forum/windows/57900/

Now my code looks like this below :

Code: Pascal  [Select]
  1. function myIPAddress() : String ;
  2. var
  3.    pSession    : HINTERNET;
  4.    hFile       : HINTERNET;
  5.    Size: DWORD;
  6.    buffer: array[1..1024] of byte;
  7.    bytesRead: DWORD;
  8. begin
  9.      pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  10.      hFile := InternetOpenUrlA(pSession,'https://bitinvestor1987.000webhostapp.com/checkip.php',nil,0,INTERNET_FLAG_RELOAD,0);
  11.      InternetReadFile(hFile,@buffer,SizeOf(buffer),bytesRead);
  12.      buffer[Size];
  13. end;
  14.  

What did i Miss
When the power of love overcomes the love of power, the world would know Peace

- Jimi Hendrix.

Thaddy

  • Hero Member
  • *****
  • Posts: 9152
Re: Get IP address in Lazarus Pascal
« Reply #1 on: June 20, 2019, 05:35:28 pm »
If it is your exposed ip you can simply use ip.thaddy.com which returns a string, not a full html page. Up since ~2000.
The response can be used immediately as a Pascal Ansistring.

I have more options, including redirects.

Using the wininet api is not a very good idea.
« Last Edit: June 20, 2019, 05:39:27 pm by Thaddy »
also related to equus asinus.

shonay

  • Full Member
  • ***
  • Posts: 165
Re: Get IP address in Lazarus Pascal
« Reply #2 on: June 20, 2019, 05:38:17 pm »
yea same same

Shows error around this area : buffer[Size];
When the power of love overcomes the love of power, the world would know Peace

- Jimi Hendrix.

Thaddy

  • Hero Member
  • *****
  • Posts: 9152
Re: Get IP address in Lazarus Pascal
« Reply #3 on: June 20, 2019, 05:40:33 pm »
Then you have to show some more code. You made mistakes.
(E.g. count from zero not one....)
« Last Edit: June 20, 2019, 05:42:19 pm by Thaddy »
also related to equus asinus.

shonay

  • Full Member
  • ***
  • Posts: 165
Re: Get IP address in Lazarus Pascal
« Reply #4 on: June 20, 2019, 05:45:55 pm »
Full code looks like this  :


Code: Pascal  [Select]
  1.  
  2. program computername;
  3.  
  4. {$mode objfpc}{$H+}
  5.  
  6. uses
  7.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  8.   cthreads,
  9.   {$ENDIF}{$ENDIF}
  10.   Classes , Windows , Wininet
  11.   { you can add units after this };
  12.  
  13. //http://www.delphibasics.info/home/delphibasicssnippets/getcomputername
  14.  
  15. function myComputerName():String;
  16. var
  17. ComputerName: Array [0 .. 256] of char;
  18. Size: DWORD;
  19. begin
  20.      Size := 256;
  21.      GetComputerName(ComputerName, Size);
  22.      Result := ComputerName;
  23. end;
  24.  
  25. function myIPAddress() : String ;
  26. var
  27.    pSession    : HINTERNET;
  28.    hFile       : HINTERNET;
  29.    Size: DWORD;
  30.    buffer: array[1..1024] of byte;
  31.    bytesRead: DWORD;
  32. begin
  33.      pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  34.      hFile := InternetOpenUrlA(pSession,'http://ip.thaddy.com/',nil,0,INTERNET_FLAG_RELOAD,0);
  35.      InternetReadFile(hFile,@buffer,SizeOf(buffer),bytesRead);
  36.      buffer[Size];
  37. end;
  38.  
  39. begin
  40.      Writeln('My computers name is : ',myComputerName());
  41.      Writeln('My computers IP is  : ',myIPAddress());
  42.      ReadLn();
  43. end.
  44.  
  45.  
When the power of love overcomes the love of power, the world would know Peace

- Jimi Hendrix.

rvk

  • Hero Member
  • *****
  • Posts: 3842
Re: Get IP address in Lazarus Pascal
« Reply #5 on: June 20, 2019, 05:46:19 pm »
What did i Miss
The original code says this:
Code: [Select]
buffer[rSize] = '\0';You just did:
Code: Pascal  [Select]
  1. buffer[Size];

Didn't you get an error on that line ????
ALWAYS show errors you get.

And you don't put the buffer into result.

You could do something like this:
Code: Pascal  [Select]
  1. function myIPAddress(): string;
  2. var
  3.   pSession: HINTERNET;
  4.   hFile: HINTERNET;
  5.   buffer: array[0..1023] of char; // make this an char-array
  6.   bytesRead: DWORD;
  7. begin
  8.   Result := 'error';
  9.   pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  10.   hFile := InternetOpenUrlA(pSession, 'http://ip.thaddy.com/', nil, 0, INTERNET_FLAG_RELOAD, 0);
  11.   if InternetReadFile(hFile, @buffer, SizeOf(buffer), bytesRead) then // don't forget to check for error
  12.   begin
  13.     buffer[bytesRead] := #0; // set the last char in the string to #0
  14.     Result := Buffer; // put the buffer in result
  15.   end;
  16. end;

Although I would do it something like this:
Code: Pascal  [Select]
  1. function myIPAddress: string;
  2. var
  3.   pSession: HINTERNET;
  4.   hFile: HINTERNET;
  5.   bytesRead: DWORD;
  6.   TempIP: string;
  7. begin
  8.   Result := 'error';
  9.   SetLength(TempIP, 1024);
  10.   pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  11.   hFile := InternetOpenUrlA(pSession, 'http://ip.thaddy.com/', nil, 0, INTERNET_FLAG_RELOAD, 0);
  12.   if InternetReadFile(hFile, PChar(TempIP), 1024, bytesRead) then
  13.   begin
  14.     SetLength(TempIP, bytesRead);
  15.     Result := TempIP;
  16.   end;
  17. end;

Also... you can search the forum for some better versions.
« Last Edit: June 20, 2019, 05:48:36 pm by rvk »

Thaddy

  • Hero Member
  • *****
  • Posts: 9152
Re: Get IP address in Lazarus Pascal
« Reply #6 on: June 20, 2019, 05:51:03 pm »
Rik, you have more patience than I have, thank you!
also related to equus asinus.

shonay

  • Full Member
  • ***
  • Posts: 165
Re: Get IP address in Lazarus Pascal
« Reply #7 on: June 20, 2019, 06:00:53 pm »
Thanks everyone its fine now. :)
When the power of love overcomes the love of power, the world would know Peace

- Jimi Hendrix.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 673
    • Lebeau Software
Re: Get IP address in Lazarus Pascal
« Reply #8 on: June 21, 2019, 08:51:19 pm »
Code: [Select]
  buffer: array[0..1023] of char; // make this an char-array

That is a bit of wasted space, considering an IPv4 address is 15 chars max, and an IPv6 address is 39 chars max.  Also, I would use AnsiChar instead of Char, since the website actually sends ASCII text, and also to avoid breaking the code in the future if Char is ever set to WideChar (via {$ModeSwitch UNICODESTRINGS} or {$Mode DelphiUnicode}).

Code: [Select]
    buffer[bytesRead] := #0; // set the last char in the string to #0
    Result := Buffer; // put the buffer in result

I wouldn't even bother with the null terminator, I would use SetString() instead.

And don't forget about cleanup to avoid resource leaks!

Code: Pascal  [Select]
  1. function myIPAddress(): string;
  2. var
  3.   pSession: HINTERNET;
  4.   hFile: HINTERNET;
  5.   buffer: array[0..45] of AnsiChar;
  6.   bytesRead: DWORD;
  7.   myIP: AnsiString;
  8. begin
  9.   Result := 'error';
  10.   pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  11.   if pSession = 0 then Exit;
  12.   try
  13.     hFile := InternetOpenUrlA(pSession, 'http://ip.thaddy.com/', nil, 0, INTERNET_FLAG_RELOAD, 0);
  14.     if hFile = 0 then Exit;
  15.     try
  16.       if InternetReadFile(hFile, @buffer, SizeOf(buffer), bytesRead) then
  17.       begin
  18.         SetString(myIP, buffer, bytesRead);
  19.         Result := string(myIP);
  20.       end;
  21.     finally
  22.       InternetCloseHandle(hFile);
  23.     end;
  24.   finally
  25.     InternetCloseHandle(pSession);
  26.   end;
  27. end;
  28. [code]
« Last Edit: June 21, 2019, 08:59:58 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

rvk

  • Hero Member
  • *****
  • Posts: 3842
Re: Get IP address in Lazarus Pascal
« Reply #9 on: June 21, 2019, 09:27:57 pm »
Code: [Select]
  buffer: array[0..1023] of char; // make this an char-array

That is a bit of wasted space, considering an IPv4 address is 15 chars max, and an IPv6 address is 39 chars max.  Also, I would use AnsiChar instead of Char, since the website actually sends ASCII text, and also to avoid breaking the code in the future if Char is ever set to WideChar (via {$ModeSwitch UNICODESTRINGS} or {$Mode DelphiUnicode}).

Code: [Select]
    buffer[bytesRead] := #0; // set the last char in the string to #0
    Result := Buffer; // put the buffer in result

I wouldn't even bother with the null terminator, I would use SetString() instead.
Yeah, that wasn't my code. TS asked about translating C++ cide wich used 1024 bytes array and put a null as terminator in the array. So I just showed how to translate.

My code used a string with setlength to reserve bytes before calling InternetReadFile.

And indeed, cleanup was not done correctly in the given code.

Also the reason I mentioned some better alternatives which can also be found here on the forum. Your code can now be counted among them  8-)