DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

ネットワーク、インターネットに接続しているか調べる

コンピュータがネットワーク、インターネットに接続しているかどうかを調べる方法を紹介します。さらに、接続状況が変化した(接続された、あるいは切断された)ことを知る方法も紹介します。

NetworkInterface.GetIsNetworkAvailableメソッドを使用する

.NET Framework 2.0以降では、NetworkInterfaceクラスのGetIsNetworkAvailableメソッドにより、ネットワーク接続が使用できるか調べることができます。

VB.NET
コードを隠すコードを選択
'ネットワークに接続されているか調べる
If System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable() Then
    Console.WriteLine("ネットワークに接続されています。")
Else
    Console.WriteLine("ネットワークに接続されていません。")
End If
C#
コードを隠すコードを選択
//ネットワークに接続されているか調べる
if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
    Console.WriteLine("ネットワークに接続されています。");
else
    Console.WriteLine("ネットワークに接続されていません。");

ヘルプによると、GetIsNetworkAvailableメソッドは、1つ以上のNetworkInterfaceのOperationalStatusプロパティがUpで、NetworkInterfaceTypeプロパティがLoopbackまたはTunnelでない場合、Trueを返すということです。つまり、NetworkInterface.GetAllNetworkInterfacesメソッドが返すNetworkInterfaceオブジェクトの配列のうち、上記の条件を満たすNetworkInterfaceが見つかれば、Trueを返すということになります。

ちなみに、ネットワークに接続しているネットワークインターフェイスの情報を表示する例をこちらで紹介しています。

補足:SystemInformation.Networkプロパティに関しても「現在ネットワーク接続が確立されているかどうかを示す」とされていますが、Networkプロパティは常にTrueを返します。

ネットワーク接続の状況が変更されたことを知る

ネットワークの接続が有効になったり、逆に無効になったことを知るためには、NetworkChangeクラスのNetworkAvailabilityChangedイベントを使用します。なお、NetworkAvailabilityChangedイベントハンドラはメインスレッドとは別のスレッドで呼び出されるため、このイベントハンドラからコントロールにアクセスするには、Invokeメソッドを使用する必要があります。

以下に例を示します。この例では、接続状況が変化したときにフォームのタイトルバーにメッセージを表示しています。このコードはフォームクラス(Form1クラス)に記述されているものとします。

VB.NET
コードを隠すコードを選択
'フォームのLoadイベントハンドラ
Private Sub Form1_Load(ByVal sender As Object, _
        ByVal e As EventArgs) Handles MyBase.Load
    'NetworkAvailabilityChangedイベントハンドラを追加
    AddHandler _
        System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged, _
        AddressOf NetworkChange_NetworkAvailabilityChanged
End Sub

'ネットワーク接続状況が変化した
Private Sub NetworkChange_NetworkAvailabilityChanged(ByVal sender As Object, _
        ByVal e As System.Net.NetworkInformation.NetworkAvailabilityEventArgs)
    'Invokeが必要か確認し、必要であればInvokeを呼び出す
    If Me.InvokeRequired Then
        Dim dlgt As New _
            System.Net.NetworkInformation.NetworkAvailabilityChangedEventHandler( _
            AddressOf NetworkChange_NetworkAvailabilityChanged)
        Me.Invoke(dlgt, New Object() {sender, e})
        Return
    End If

    If e.IsAvailable Then
        Me.Text = "ネットワーク接続が有効になりました。"
    Else
        Me.Text = "ネットワーク接続が無効になりました。"
    End If
End Sub
C#
コードを隠すコードを選択
//フォームのLoadイベントハンドラ
private void Form1_Load(object sender, EventArgs e)
{
    //NetworkAvailabilityChangedイベントハンドラを追加
    System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged +=
        new System.Net.NetworkInformation.NetworkAvailabilityChangedEventHandler(
        NetworkChange_NetworkAvailabilityChanged);
}

//ネットワーク接続状況が変化した
private void NetworkChange_NetworkAvailabilityChanged(
    object sender, System.Net.NetworkInformation.NetworkAvailabilityEventArgs e)
{
    //Invokeが必要か確認し、必要であればInvokeを呼び出す
    if (this.InvokeRequired)
    {
        System.Net.NetworkInformation.NetworkAvailabilityChangedEventHandler dlgt =
            new System.Net.NetworkInformation.NetworkAvailabilityChangedEventHandler(
                NetworkChange_NetworkAvailabilityChanged);
        this.Invoke(dlgt, new object[] { sender, e });
        return;
    }

    if (e.IsAvailable)
        this.Text = "ネットワーク接続が有効になりました。";
    else
        this.Text = "ネットワーク接続が無効になりました。";
}

My.Computer.Network.IsAvailableプロパティを使用する

.NET Framework 2.0以降のVB.NETでは、My.Computer.Network.IsAvailableプロパティを使用してネットワークに接続されているか調べることもできます。NetworkInterface.GetIsNetworkAvailableと全く同じです。

さらに、My.Computer.Network.NetworkAvailabilityChangedイベントで接続状態が変化したことを知ることができます。これもNetworkChange.NetworkAvailabilityChangedイベントとほぼ同じようですが、イベントハンドラはメインスレッド(イベントハンドラを追加したスレッド)と同じスレッドで呼び出されるようなので、Invokeメソッドを使用する必要がありません。

VB.NET
コードを隠すコードを選択
'フォームのLoadイベントハンドラ
Private Sub Form1_Load(ByVal sender As Object, _
        ByVal e As EventArgs) Handles MyBase.Load
    'ネットワークに接続されているか調べる
    If My.Computer.Network.IsAvailable Then
        Console.WriteLine("ネットワークに接続されています")
    Else
        Console.WriteLine("ネットワークに接続されていません")
    End If

    'NetworkAvailabilityChangedイベントハンドラを追加
    AddHandler _
        My.Computer.Network.NetworkAvailabilityChanged, _
        AddressOf Network_NetworkAvailabilityChanged
End Sub

'ネットワーク接続状況が変化した
Private Sub Network_NetworkAvailabilityChanged(ByVal sender As Object, _
        ByVal e As Devices.NetworkAvailableEventArgs)
    If e.IsNetworkAvailable Then
        Console.WriteLine("ネットワーク接続が有効になりました。")
    Else
        Console.WriteLine("ネットワーク接続が無効になりました。")
    End If
End Sub

WinINet APIのInternetGetConnectedState関数を使用する

WinINet APIのInternetGetConnectedState関数を使用してインターネットに接続されているか調べることができます。

VB.NET
コードを隠すコードを選択
<System.Runtime.InteropServices.DllImport("wininet.dll")> _
Shared Function InternetGetConnectedState( _
    ByRef lpdwFlags As Integer, ByVal dwReserved As Integer) As Boolean
End Function

'Button1のClickイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
        ByVal e As EventArgs) Handles Button1.Click
    'インターネットに接続されているか確認する
    Dim flags As Integer
    If InternetGetConnectedState(flags, 0) Then
        Console.WriteLine("インターネットに接続されています。")
    Else
        Console.WriteLine("インターネットに接続されていません。")
    End If
End Sub
C#
コードを隠すコードを選択
[System.Runtime.InteropServices.DllImport("wininet.dll")]
extern static bool InternetGetConnectedState(out int lpdwFlags, int dwReserved);

//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
    //インターネットに接続されているか確認する
    int flags;
    if (InternetGetConnectedState(out flags, 0))
        Console.WriteLine("インターネットに接続されています。");
    else
        Console.WriteLine("インターネットに接続されていません。");
}

InternetGetConnectedState関数を使ってインターネットとの接続状況の変更を知るには、タイマーにより定期的にチェックするようにすればよいでしょう。

実際に接続を試みることにより確かめる

上記のような方法では、実際にインターネットに接続しているかは分かりません。実際にインターネットに接続しているかを調べるのは、インターネットに接続されていれば間違いなく応答を返すサーバーにPingを送信したり、実際に接続を試みたりする必要があります。

ここでは、HTTPのHEADメソッドにより調べる方法を紹介します(Pingを使用する例は、こちらをご覧ください)。ただし、このようにいきなり接続を要求しようとするとダイヤルアップ接続ダイアログが表示されてしまう可能性がありますので、GetIsNetworkAvailableメソッドやInternetGetConnectedState関数がtrueを返したときに以下のように確認するとしたほうが良いでしょう。

VB.NET
コードを隠すコードを選択
''' <summary>
''' インターネットに接続されているか
''' </summary>
''' <returns>接続されているときはtrue</returns>
Public Shared Function IsInternetConnected() As Boolean
    'インターネットに接続されているか確認する
    Dim host As String = "http://www.yahoo.com"

    Dim webreq As System.Net.HttpWebRequest = Nothing
    Dim webres As System.Net.HttpWebResponse = Nothing
    Try
        'HttpWebRequestの作成
        webreq = CType(System.Net.WebRequest.Create(host), _
            System.Net.HttpWebRequest)
        'メソッドをHEADにする
        webreq.Method = "HEAD"
        '受信する
        webres = CType(webreq.GetResponse(), System.Net.HttpWebResponse)
        '応答ステータスコードを表示
        Console.WriteLine(webres.StatusCode)
        Return True
    Catch
    Finally
        If Not (webres Is Nothing) Then
            webres.Close()
        End If
    End Try
End Function

'Button1のClickイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
        ByVal e As EventArgs) Handles Button1.Click
    If IsInternetConnected() Then
        Console.WriteLine("インターネットに接続されています。")
    Else
        Console.WriteLine("インターネットに接続されていません。")
    End If
End Sub
C#
コードを隠すコードを選択
/// <summary>
/// インターネットに接続されているか
/// </summary>
/// <returns>接続されているときはtrue</returns>
public static bool IsInternetConnected()
{
    //インターネットに接続されているか確認する
    string host = "http://www.yahoo.com";

    System.Net.HttpWebRequest webreq = null;
    System.Net.HttpWebResponse webres = null;
    try
    {
        //HttpWebRequestの作成
        webreq = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(host);
        //メソッドをHEADにする
        webreq.Method = "HEAD";
        //受信する
        webres = (System.Net.HttpWebResponse)webreq.GetResponse();
        //応答ステータスコードを表示
        Console.WriteLine(webres.StatusCode);
        return true;
    }
    catch
    {
        return false;
    }
    finally
    {
        if (webres != null)
            webres.Close();
    }
}

//Button1のClickイベントハンドラ
private void Button1_Click(object sender, EventArgs e)
{
    if (IsInternetConnected())
        Console.WriteLine("インターネットに接続されています。");
    else
        Console.WriteLine("インターネットに接続されていません。");
}
  • 履歴:
  • 2011/2/2 誤字修正。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。