Are we connected to the internet?
I have found at least 10 different solutions for this, but to date this is the only version that actually does the job correctly. Checking and verifying that your application has access to the Internet is not as straight forward as it may seem. The current connection can be registered in Windows as active when it’s really not. You may be connected to your router but the IP is invalid (cable from router unplugged) or the gateway may refuse your winsock dispatcher access (forgot to pay your bill?). The following code checks all 3 scenarios and makes absolutely sure you have access.
If you want to simulate network detection (so your app is network aware), place the verification call inside a timer, and activate the timer whenever you get service/socket level exceptions from Indy.
uses WinInet, winsock; (* Dont call this one, it's used by the proc below! *) Function JL_VerifyIPAddr:Boolean; type TaPInAddr = Array[0..10] of PInAddr; PaPInAddr = ^TaPInAddr; var phe: PHostEnt; pptr: PaPInAddr; Buffer: Array[0..63] of Char; I: Integer; GInitData: TWSAData; IP: AnsiString; FInit: Boolean; Begin (* Default to false *) Result := False; (* Initialize Windows sockets. The reason we dont explicitly act on the results is because WSA is "per process". In other words, indy might have initialized WSA already. *) FInit:=WSAStartup($101, GInitData)=0; try (* Get the local hostname *) if GetHostName(Buffer, SizeOf(Buffer))=0 then Begin (* Get host structure by name *) phe := GetHostByName(buffer); if phe<>NIL then Begin (* Get a PTR to adress list *) pPtr := PaPInAddr(phe^.h_addr_list); if pPtr<>NIL then Begin (* Build IP from list *) I := 0; while pPtr^[I] <> nil do begin IP := inet_ntoa(pptr^[I]^); Inc(I); end; (* Check IP *) Result := (IP <> '') and (IP <> '127.0.0.1'); end; end; end; finally If FInit then WSACleanup; end; end; function JL_VerifyInternetConnection: boolean; const FLAG_ICC_FORCE_CONNECTION = 1; INTERNET_CONNECTION_OFFLINE = 32; var dwConnectionTypes : DWORD; begin (* default to negative *) result:=False; (* check what windows in general is saying. This is the correct way to call this API method. The typical examples elsewhere screw this up. See: http://msdn.microsoft.com/en-us/library/aa384702%28VS.85%29.aspx *) dwConnectionTypes:=0; InternetGetConnectedState(@dwConnectionTypes,0); If (dwConnectionTypes and INTERNET_CONNECTION_OFFLINE) =INTERNET_CONNECTION_OFFLINE then exit; (* check that we actually have an IP adresse *) If JL_VerifyIPAddr=false then exit; (* try to ping an URL that we know exists *) result:=InternetCheckConnection('http://www.microsoft.com', FLAG_ICC_FORCE_CONNECTION,0); end;