インターネット接続確認をするには?

解決


勉強  2003-12-18 07:03:25  No: 6298

以前この掲示板でも質問があったようですが、
回答のURLがなくなっている為、改めて質問させていただきます。

WinInetのAPIでインターネット接続確認をしたく
現在InternetAttemptConnectを使っていますが、
ADSLのモデムを切断している際にアプリケーションが固まってしまいます。

対処方法などありましたら、是非ご教授お願いします。


にしの  2003-12-18 07:49:20  No: 6299

ADSLはLAN接続扱いですので、
InternetGetConnectedState
を使うとよろしいかと思います。

余談ですが、この掲示板のログに無ければ、googleなどで検索すれば見つかるかもしれませんよ。googleにはキャッシュがあり、実際には消えていても、検索で引っかかればキャッシュに残っているかもしれません。


勉強  2003-12-19 07:45:56  No: 6300

InternetGetConnectedState 使用してみましたが、接続していないのに接続していると認識されました。
googleで色々なワードで検索しましたが、InternetAttemptConnect,InternetGetConnectedState 以外に有用な情報は見つかりませんでした。もちろんキャッシュも確かめました。
検索のワードがよろしくないのでしょうか?


にしの  2003-12-19 10:11:58  No: 6301

うちの環境では、InternetGetConnectedStateでLAN接続中/切断中が判別できます。
戻り値でなく、Flagsの値はどうなっています?
それと、ADSLのモデムを切っているときのIPアドレスはどうなっているのでしょうか。
もちろん、ルータが生きていればWANには接続できなくともInternetGetConnectedStateはTrueを返すと思います。ルータにもつながっていない状態でしょうか。


Halbow  2003-12-19 10:34:08  No: 6302

Halbow です。

ちょっと試してみました。

uses
  WinInet;

const
  INTERNET_RAS_INSTALLED         =$10;
  INTERNET_CONNECTION_OFFLINE    =$20;
  INTERNET_CONNECTION_CONFIGURED =$40;

procedure TForm1.Button1Click(Sender: TObject);
var
  Flag:DWORD;
begin
  Memo1.Clear;
  if InternetGetConnectedState(@Flag,0) then begin
    if (Flag and INTERNET_CONNECTION_MODEM) <> 0 then
       Memo1.Lines.Add('CONNECTION_MODEM');
    if (Flag and INTERNET_CONNECTION_LAN) <> 0 then
       Memo1.Lines.Add('CONNECTION_LAN');
    if (Flag and INTERNET_CONNECTION_PROXY) <> 0 then
       Memo1.Lines.Add('CONNECTION_PROXY');
    if (Flag and INTERNET_RAS_INSTALLED) <> 0 then
       Memo1.Lines.Add('RAS_INSTALLED');
    if (Flag and INTERNET_CONNECTION_OFFLINE) <> 0 then
       Memo1.Lines.Add('CONNECTION_OFFLINE');
    if (Flag and INTERNET_CONNECTION_CONFIGURED) <> 0 then
       Memo1.Lines.Add('CONNECTION_CONFIGURED');
  end else
    Memo1.Lines.Add('No Connection');
end;

わたしの自宅では ADSL ですが、正常につながっているときも、無線 LAN カード
を引っこ抜いたとき(従ってルータにもつながっていない)も同じように Memo1 には

CONNECTION_LAN
RAS_INSTALLED

と表示されて、接続の有無は確認できませんでした。D5 sp1 in Win2k sp4 です。


Halbow  2003-12-19 12:08:10  No: 6303

Halbow です。

> 接続の有無は確認できませんでした。

これですが、取り外した直後はやはり確認できないのですが、そのまま放っておいて
5,6分後にまたボタンを押したら、

No Connection

と表示されました。再び 無線LANカードを押し込むと、10秒後でも

CONNECTION_LAN
RAS_INSTALLED

と表示されました。ですから、接続は素早く検出できますが、切断を検出するのには
少し時間がかかるようです。


Halbow  2003-12-19 12:24:11  No: 6304

Halbow です。

なんどもすみません。特定サイトにアクセスしてピングする感じで

uses
  WinInet;

function CheckInternetConnect:Boolean;
var
  hOpen,hURL:HINTERNET;
begin
  result := false;

  hOpen := InternetOpen('CIAAgent',INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
  if not Assigned(hOpen) then exit;

  hURL := InternetOpenURL(hOpen,'http://www.google.com/intl/ja/',nil,0,0,0);
  if not Assigned(hURL) then begin
    InternetCloseHandle(hOpen);
    exit;
  end;

  InternetCloseHandle(hURL);
  InternetCloseHandle(hOpen);

  result := true;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if CheckInternetConnect then
    Label1.Caption := 'Connected'
  else
    Label1.Caption := 'Disconnected';
end;

こんなふうにしたら、接続・切断ともに数秒のうちに確認できました。


にしの  2003-12-19 18:25:11  No: 6305

InternetOpenって、キャッシュを拾ったりしませんか?
前にそんなのがあったような気がします。


Halbow  2003-12-19 19:06:08  No: 6306

Halbow です。

> InternetOpenって、キャッシュを拾ったりしませんか?

さぁ、今回がはじめての WEB プログラミングでしたのでしりませんが、
InternetOpenURL() はこちらではキャッシュを拾いませんねぇ。
IE の設定にもよるのかも知れません。切断時に、IE を立ち上げると
自動的にオフライン表示するようになっている場合はキャッシュを
拾う可能性があるかもしれませんね。わたしの環境では
InternetGetConnectedState() よりは迅速な確認ができているようです。


にしの  2003-12-19 19:29:59  No: 6307

InternetOpenURLでキャッシュを取得するかどうかはちょっとテストしてみます。
結果は後ほど。

別の案を。
GetIfTableを使用すれば、LANの状態は見れそうです。
ダイアルアップの環境がないので、そちらのテストはできていませんが。

うちでは、接続されている場合は、dwOperStatusが5(MIB_IF_OPER_STATUS_OPERATIONAL)が返り、切断されている場合は、dwOperStatusが0(MIB_IF_OPER_STATUS_NON_OPERATIONAL)が返ってきました。

サンプルソースです。
//----------------------------------------------------
//関数の定義Unit
unit IPHLPAPI;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes;

Const
     MAX_INTERFACE_NAME_LEN             = $100;
     ERROR_SUCCESS                      = 0;
     MAXLEN_IFDESCR                     = $100;
     MAXLEN_PHYSADDR                    = 8;

     MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0 ;
     MIB_IF_OPER_STATUS_UNREACHABLE     = 1;
     MIB_IF_OPER_STATUS_DISCONNECTED    = 2;
     MIB_IF_OPER_STATUS_CONNECTING      = 3;
     MIB_IF_OPER_STATUS_CONNECTED       = 4;
     MIB_IF_OPER_STATUS_OPERATIONAL     = 5;

     MIB_IF_TYPE_OTHER                  = 1;
     MIB_IF_TYPE_ETHERNET               = 6;
     MIB_IF_TYPE_TOKENRING              = 9;
     MIB_IF_TYPE_FDDI                   = 15;
     MIB_IF_TYPE_PPP                    = 23;
     MIB_IF_TYPE_LOOPBACK               = 24;
     MIB_IF_TYPE_SLIP                   = 28;

     MIB_IF_ADMIN_STATUS_UP             = 1;
     MIB_IF_ADMIN_STATUS_DOWN           = 2;
     MIB_IF_ADMIN_STATUS_TESTING        = 3;

TYPE
   MIB_IFROW            = Record
         wszName              : Array[0 .. (MAX_INTERFACE_NAME_LEN*2-1)] of char;
         dwIndex              : LongInt;
         dwType               : LongInt;
         dwMtu                : LongInt;
         dwSpeed              : LongInt;
         dwPhysAddrLen        : LongInt;
         bPhysAddr            : Array[0 .. (MAXLEN_PHYSADDR-1)] of Byte;
         dwAdminStatus        : LongInt;
         dwOperStatus         : LongInt;
         dwLastChange         : LongInt;
         dwInOctets           : LongInt;
         dwInUcastPkts        : LongInt;
         dwInNUcastPkts       : LongInt;
         dwInDiscards         : LongInt;
         dwInErrors           : LongInt;
         dwInUnknownProtos    : LongInt;
         dwOutOctets          : LongInt;
         dwOutUcastPkts       : LongInt;
         dwOutNUcastPkts      : LongInt;
         dwOutDiscards        : LongInt;
         dwOutErrors          : LongInt;
         dwOutQLen            : LongInt;
         dwDescrLen           : LongInt;
         bDescr               : Array[0 .. (MAXLEN_IFDESCR - 1)] of Char;
  end;
  MIB_IFTABLE=record
    dwNumEntries: DWORD;
    table: Array[0 .. (MAXLEN_PHYSADDR-1)] of MIB_IFROW;
  end;
  PMIB_IFTABLE=^MIB_IFTABLE;

Function GetIfTable(
   pIfTable        : Pointer;
   VAR pdwSize     : LongInt;
   bOrder          : LongInt
   ): LongInt;  StdCall;

implementation

Function GetIfTable;          stdcall; external   'IPHLPAPI.DLL';

end.

//-----------------------------------------------------------
//こちらが使用例
uses
  IPHLPAPI;

procedure TForm1.Button1Click(Sender: TObject);
var
  Buf: array[0..1023] of char;
  d: Integer;
  IfTable: PMIB_IFTABLE;
  i: integer;
begin
  d := 0;

  GetIfTable(nil, d, 0);
  IfTable := SysGetMem(d);

  if Assigned(IfTable) then
  begin
    if  GetIfTable(IfTable, d,0) = NO_ERROR then
    begin
      for i := 0 to IfTable.dwNumEntries - 1 do
      begin
        Memo1.Lines.Add('');

        Memo1.Lines.Add('dwIndex 0x' + IntToHex(IfTable.table[i].dwIndex, 8));
        case IfTable.table[i].dwType of
        MIB_IF_TYPE_OTHER:
          Memo1.Lines.Add('dwType MIB_IF_TYPE_OTHER');
        MIB_IF_TYPE_ETHERNET:
          Memo1.Lines.Add('dwType MIB_IF_TYPE_ETHERNET');
        MIB_IF_TYPE_TOKENRING:
          Memo1.Lines.Add('dwType MIB_IF_TYPE_TOKENRING');
        MIB_IF_TYPE_FDDI:
          Memo1.Lines.Add('dwType MIB_IF_TYPE_FDDI');
        MIB_IF_TYPE_PPP:
          Memo1.Lines.Add('dwType MIB_IF_TYPE_PPP');
        MIB_IF_TYPE_LOOPBACK:
          Memo1.Lines.Add('dwType MIB_IF_TYPE_LOOPBACK');
        MIB_IF_TYPE_SLIP:
          Memo1.Lines.Add('dwType MIB_IF_TYPE_SLIP');
        end;
        Memo1.Lines.Add('dwMtu ' + IntToStr(IfTable.table[i].dwMtu));
        Memo1.Lines.Add('dwSpeed ' + IntToStr(IfTable.table[i].dwSpeed));

        Memo1.Lines.Add('dwPhysAddrLen ' + IntToStr(IfTable.table[i].dwPhysAddrLen));

        Memo1.Lines.Add('bPhysAddr ' + 
                  IntToHex(Integer(IfTable.table[i].bPhysAddr[0]), 2) +
                  IntToHex(Integer(IfTable.table[i].bPhysAddr[1]), 2) +
                  IntToHex(Integer(IfTable.table[i].bPhysAddr[2]), 2) +
                  IntToHex(Integer(IfTable.table[i].bPhysAddr[3]), 2) +
                  IntToHex(Integer(IfTable.table[i].bPhysAddr[4]), 2) +
                  IntToHex(Integer(IfTable.table[i].bPhysAddr[5]), 2)
          );

        Memo1.Lines.Add('dwAdminStatus ' + IntToStr(IfTable.table[i].dwAdminStatus));
        Memo1.Lines.Add('dwOperStatus ' + IntToStr(IfTable.table[i].dwOperStatus));
        Memo1.Lines.Add('dwLastChange ' + IntToStr(IfTable.table[i].dwLastChange));
        Memo1.Lines.Add('dwInOctets ' + IntToStr(IfTable.table[i].dwInOctets));
        Memo1.Lines.Add('dwInUcastPkts ' + IntToStr(IfTable.table[i].dwInUcastPkts));
        Memo1.Lines.Add('dwInNUcastPkts ' + IntToStr(IfTable.table[i].dwInNUcastPkts));
        Memo1.Lines.Add('dwInDiscards ' + IntToStr(IfTable.table[i].dwInDiscards));
        Memo1.Lines.Add('dwInErrors ' + IntToStr(IfTable.table[i].dwInErrors));
        Memo1.Lines.Add('dwInUnknownProtos ' + IntToStr(IfTable.table[i].dwInUnknownProtos));
        Memo1.Lines.Add('dwOutOctets ' + IntToStr(IfTable.table[i].dwOutOctets));
        Memo1.Lines.Add('dwOutUcastPkts ' + IntToStr(IfTable.table[i].dwOutUcastPkts));
        Memo1.Lines.Add('dwOutNUcastPkts ' + IntToStr(IfTable.table[i].dwOutNUcastPkts));
        Memo1.Lines.Add('dwOutDiscards ' + IntToStr(IfTable.table[i].dwOutDiscards));
        Memo1.Lines.Add('dwOutErrors ' + IntToStr(IfTable.table[i].dwOutErrors));
        Memo1.Lines.Add('dwOutQLen ' + IntToStr(IfTable.table[i].dwOutQLen));
        Memo1.Lines.Add('dwDescrLen ' + IntToStr(IfTable.table[i].dwDescrLen));

        IfTable.table[i].bDescr[IfTable.table[i].dwDescrLen]:=#0;
        Memo1.Lines.Add('bDescr ' + IfTable.table[i].bDescr);
      end;
    end;
    SysFreeMem(IfTable);
  end;


にしの  2003-12-19 19:36:03  No: 6308

InternetOpenURLのテストをしてみました。

オフラインで使用するにしてあっても問題なさそうです。
# WindowsXP Pro, IE6.0.2800.1106, Delphi7 Pro


勉強  2003-12-21 08:54:07  No: 6309

ありがとう


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加