Get external IP address without error if there is no internet lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Libra07 · 2022-12-03 13:51 I wrote a function that returns the IP address. It works fine, if I have internet. But if I have no internet, it stops with error message 217 . My functions use FpHttpClient unit. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Function Get_Public_IP:String;       // #1Var   IdGetIP  : TFPHTTPClient;      Temp_IP  : String;      I:Longint;Const URL_List : Array[1..2] Of String               = ('http://dynupdate.no-ip.com/ip.php',                'http://ipinfo.io/ip');Begin  Temp_IP:='0.0.0.0';   IdGetIP := TFPHTTPClient.Create(nil);  Temp_IP := IdGetIP.Get(URL_List[1]);  IdGetIP.Free;   Get_Public_IP:=Temp_IP;End;  I read about it and tried another code, with TRY and EXCEPT, but it also works fine when i have is internet, but stops with an error 217 when there is no internet. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Function Get_Public_IP:String;       // #2Var  IdGetIP : TFPHTTPClient;  Html  : String;Const  gUrlIpA = 'http://dynupdate.no-ip.com/ip.php';  gUrlIpB = 'http://ipinfo.io/ip';Begin  Try    IdGetIP:=TFPHTTPClient.Create(nil);    Result := '';    Try      Html := IdGetIP.Get(gUrlIpA);    Except      Html := IdGetIP.Get(gUrlIpB);    End;    Result := Html;  Finally    IdGetIP.Free;  End;End;  How can I extend my code to handle this error and not stop when there is no internet? It's good for me if the functions return with '0.0.0.0' ip address, if I have no internet. ---------------------------------------------------------------------- Libra07 · 2022-12-03 14:13 When I entered the two source codes here, I found the solution. I edited the second source code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Function Get_Public_IP:String;       // #2Var  IdGetIP : TFPHTTPClient;  Html  : String;Const  gUrlIpA = 'http://dynupdate.no-ip.com/ip.php';  gUrlIpB = 'http://ipinfo.io/ip';Begin  Try    IdGetIP:=TFPHTTPClient.Create(nil);    Result := '';    Try      Html := IdGetIP.Get(gUrlIpA);    Except      Html := '0.0.0.0';    End;    Result := Html;  Finally    IdGetIP.Free;  End;End; ---------------------------------------------------------------------- MarkMLl · 2022-12-03 16:44 So the basic problem would appear to be that your computer or site is relying on an external name server (DNS etc.) to resolve e.g. http://ipinfo.io/ip to a dotted-quad address. This whole area is rather fraught, since there is a vast number of possibilities relating to nameserver fallback etc. In fact your problems will really start when you try to work out whether you currently have a live route to the Internet at large. MarkMLl ---------------------------------------------------------------------- Dzandaa · 2022-12-03 17:49 Hi, You can try a validate function on the URL: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function CheckValidUrl(URL: String): integer;var HTTPSender: THTTPSend;begin  HTTPSender := THTTPSend.Create;  HTTPSender.Timeout := 50; try   HTTPSender.HTTPMethod('GET', URL);   if (HTTPSender.ResultCode >= 100) and (HTTPSender.ResultCode<=302) then Result := 0   else Result := HTTPSender.ResultCode; finally   HTTPSender.Free; end;end; If the function return 0, it's O.K. B-> ---------------------------------------------------------------------- KodeZwerg · 2022-12-03 18:21 I am using mostly same code (specific for Windows) that user Remy Lebeau posted here. (Just to mention it, since I do not know about anything what the target platform is.) ---------------------------------------------------------------------- Dzandaa · 2022-12-03 18:33 Hi, Work for Windows and Linux. B-> ---------------------------------------------------------------------- Remy Lebeau · 2022-12-04 02:21 Quote from: Libra07 on December 03, 2022, 02:51:44 pmI wrote a function that returns the IP address. It works fine, if I have internet. But if I have no internet, it stops with error message 217 . My functions use FpHttpClient unit. You need a try..except around EVERY call to TFPHTTPClient.Get().  In your first attempt, you aren't catching any errors at all.  In your second attempt, you are catching errors only on the 1st call but not the 2nd call.  In your third attempt, you are only querying 1 URL, but at least you are catching errors for it. Try something more like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function Get_Public_IP: String;var  IdGetIP : TFPHTTPClient;  I : LongInt;cconst  URL_List : array[1..2] of string = (    'http://dynupdate.no-ip.com/ip.php',    'http://ipinfo.io/ip'  );begin  Result := '0.0.0.0';  IdGetIP := TFPHTTPClient.Create(nil);  try    for I := Low(URL_List) to High(URL_List) do    try      Result := IdGetIP.Get(URL_List[I]);      Break;    except    end;  finally  IdGetIP.Free;  end;end; ---------------------------------------------------------------------- Libra07 · 2022-12-05 11:13 Remy Lebeau, thank you! Your idea is very good and works fine, but speed is important to me, so I would like to query an external URL. If this doesn't work for some reason in the future, I'll replace the URL with the other one. I couldn't try Remy's other code, the myIPAddress() function, because I couldn't find the UNIT that contains the HINTERNET type. Which UNIT is this? I'm sure that you can't query the external IP address without an external DNS URL, right? This can't be solved with internal resources, can it? ---------------------------------------------------------------------- balazsszekely · 2022-12-05 11:25 @Libra07 QuoteI couldn't try Remy's other code, the myIPAddress() function, because I couldn't find the UNIT that contains the HINTERNET type. Which UNIT is this?uses WinINet ---------------------------------------------------------------------- Libra07 · 2022-12-05 11:47 @GetMem Thank you GetMem! Now I can compile the code but I have an error message in 2 rows: "Error: Operator is not overloaded: Pointer = ShortInt". 11.  :  if pSession = 0 then Exit; 14.  :  if hFile = 0 then Exit; After I edited this rows to this, I can compile the source code. 11.  :  if pSession = nil then Exit; 14.  :  if hFile = nil then Exit; But finally the function returned an empty value. I relpaced the DNS URL too this: 'http://ip.thaddy.com/' -> 'http://dynupdate.no-ip.com/ip.php' Now it's working fine! Thank you! If I can help anyone with this, this is the second source code that works well: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Program Get_External_IP_Address_2; Uses WinINet; function myIPAddress(): string;var  pSession: HINTERNET;  hFile: HINTERNET;  buffer: array[0..45] of AnsiChar;  bytesRead: DWORD;  myIP: AnsiString;begin  Result := 'error';  pSession := InternetOpen(nil, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);  if pSession = nil then Exit;    // Old value: 0  try    hFile := InternetOpenUrlA(pSession, 'http://dynupdate.no-ip.com/ip.php', nil, 0, INTERNET_FLAG_RELOAD, 0);    if hFile = nil then Exit;    // Old value: 0    try      if InternetReadFile(hFile, @buffer, SizeOf(buffer), bytesRead) then      begin        SetString(myIP, buffer, bytesRead);        Result := string(myIP);      end;    finally      InternetCloseHandle(hFile);  end;  finally    InternetCloseHandle(pSession);  end;end; Begin  Write('IP: ');  WriteLn(myIPAddress);  ReadLn;End. ---------------------------------------------------------------------- Warfley · 2022-12-05 13:24 Just on a conceptual level, if you are not connected to the Internet, you don't have a internet accessible IP address, so the question is what does your function retrun. You can return the empty string, but in the socket API the NULL string (which is equivalent to the empty string in Pascal) is resolved to the loopback address (127.0.0.1 in IPv4 or ::1 in IPv6). An alternative is that you could return the 0 address (0.0.0.0 in IPv4 or ::0 in IPv6), but this address has other special purposes, e.g. it binds any address. Also there is the question, when you return a dummy address like the 0 address, if you should return an IPv4 or IPv6 address. Therefore I would suggest that the usage of exceptions to signal that there is no internet connection (and therefore no meaningful external IP address), is actually a good solution for the issue at hand. When calling your function, it either returns a valid IP address, or it raises an exception. Then you avoid the problem with adding a bottom element to a type which is not intended to have a bottom element ---------------------------------------------------------------------- BobDog · 2022-12-05 13:24 Here is a winsock way for www Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   {$mode objfpc}{$apptype console} useswinsock; function GetSiteAddress(Site:pc har='www.freepascal.org'):ansistring;typelwp=^longword;varanswer:ansis tring='';   _wsDAT:WSADATA;   addr:in_addr;   res:^hostent;   i:integer=0;     begin   _wsDAT.wversion:=0;   _wsDAT.wHighVersion:=0;;    WSAStartup(514,twsadata(_wsDAT));   res := gethostbyname(Site);   answer:=answer+site+chr(10);   if (res=nil) then    begin    WSACleanup();    answer:=answer+'Error - Site not found'+chr(10);    exit(answer);   end   else   begin   while ((res^.h_addr_list[i]) <> nil) do   begin   addr.s_addr:= lwp((res^).h_addr_list[i])^;   answer:=answer+inet_ntoa(addr)+chr(10);      i:=i+1;   end;   WSACleanup();   end;   exit(answer);end;     beginwriteln(GetSiteAddr ess());;writeln(GetSiteAddress('www.google.com'));writeln(GetSiteAddre ss('www.nosuchsiteexists.com'));writeln(GetSiteAddress('www.Youtube.co m'));writeln(GetSiteAddress('www.Wikipedia.org'));writeln(GetSiteAddre ss('www.Yahoo.com'));writeln('Press return to end . . .');readln;end. ---------------------------------------------------------------------- Libra07 · 2022-12-05 14:00 BobDog, this is very nice solution to identify the IP address of a site! Thank you!