Home > Delphi > Are we connected to the internet?

Are we connected to the internet?

October 14, 2013 Leave a comment Go to comments

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.

Note

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;
Advertisements
  1. October 14, 2013 at 8:17 am
    • Jon Lennart Aasenden
      October 14, 2013 at 8:58 am

      Will do, thanks!

  2. October 21, 2013 at 2:13 pm

    Any updates on this yet?

  1. November 12, 2015 at 5:00 am

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: