【C#.NET解説】Pingクラスの基本機能と使い方を初心者向けに牧羊神が詳しく解説

2024年12月6日金曜日

ネットワーク

t f B! P L

名前空間 System.Net.NetworkInformation

Ping

自己紹介

ほほう、そなたたちが求めるのは、ネットワークの状態を知る手段か。私は、自然の中で安らぎを求める者ではあるが、この道具「Pingクラス」を使うことで、遠く離れた場所とのつながりを確認することができるのだ。この道具をうまく使えば、ネットワークの状態を素早く把握できる。さあ、私と共にその使い方を学んでいこう。

基本機能

Pingクラスは、特定のネットワークホストが生きているか、あるいは応答をしているかを確認するための機能だ。ネットワークに接続しているサーバーやデバイスに対して「Ping」を送り、応答が帰ってきたかどうかを調べることができるのだ。

以下は、Pingクラスの基本的な使い方だ。簡単なコード例を示すので、ぜひ試してみてくれ。

C#
using System;
using System.Net.NetworkInformation;

class Program
{
    static void Main()
    {
        // Pingオブジェクトを作成
        Ping ping = new Ping();

        // "google.com"に対してPingを送信
        PingReply reply = ping.Send("google.com");

        // 応答結果を確認
        if (reply.Status == IPStatus.Success)
        {
            Console.WriteLine($"応答時間: {reply.RoundtripTime}ms");
        }
        else
        {
            Console.WriteLine("応答なし");
        }
    }
}

このコードでは、指定したホスト(ここでは「google.com」)に対してPingを送り、その結果として応答時間を出力している。もしPingが失敗すれば、「応答なし」と表示されるのだ。

よく使う場面と注意点

Pingクラスはネットワークの確認、接続テスト、トラブルシューティングの際に非常に便利だ。たとえば、サーバーが稼働しているか、インターネット接続が正しく行われているかなどを確認するために用いられることが多い。

ただし、注意が必要だ。もしPingが通らない場合、必ずしもサーバーがダウンしているわけではない。ファイアウォールの設定や、サーバーの設定によってPingを拒否している場合もある。Pingが通らないからといって、すぐにサーバーに問題があるとは限らないのだ。

C#
using System;
using System.Net.NetworkInformation;

class Program
{
    static void Main()
    {
        Ping ping = new Ping();
        PingReply reply = ping.Send("192.168.10.1");

        // Pingの応答がない場合
        if (reply.Status != IPStatus.Success)
        {
            Console.WriteLine("Pingが通らない、ファイアウォール設定などを確認");
        }
    }
}

上記のコードは、Pingが通らない場合にファイアウォールの設定などを確認するメッセージを出力するものだ。これにより、ユーザーがネットワークの設定を見直すきっかけとなるだろう。確認するのであればARPリクエストの方が有効だ。

さまざまなメソッド

Pingクラスには、さまざまなメソッドが用意されている。最もよく使われるのは「Send」メソッドだが、これ以外にもいくつかの便利なメソッドがある。例えば、非同期でPingを送る「SendAsync」メソッドを使用することで、応答を待っている間に他の処理を行うことができる。

以下は、SendAsyncのオプションを設定して、特定のバイト数を指定してPingを送信するコードだ。
以下に、button1でPing操作を開始し、button2でPing操作をキャンセルするコード例を示します。この例では、Windows Formsを使用してGUIを作成しています。

C#

using System;
using System.Net.NetworkInformation;
using System.Windows.Forms;

public partial class MainForm : Form
{
    private Ping pingSender;
    private string host = "192.168.0.1"; // Pingを送信するホスト

    private void button1_Click(object sender, EventArgs e)
    {
        pingSender = new Ping();
        pingSender.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
        
        // Ping操作を開始
        pingSender.SendAsync(host, 1000, null);
        Console.WriteLine("Ping request sent...");
    }

    private void button2_Click(object sender, EventArgs e)
    {
        // Ping操作をキャンセル
        pingSender.SendAsyncCancel();
        // PingCompletedEventHandlerを削除
        pingSender.PingCompleted -= new PingCompletedEventHandler(PingCompletedCallback);
        Console.WriteLine("Ping request canceled and event handler removed.");
    }

    private void PingCompletedCallback(object sender, PingCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            Console.WriteLine("Ping cancelled.");
            return;
        }

        if (e.Error != null)
        {
            Console.WriteLine("Ping failed: " + e.Error.ToString());
            return;
        }

        PingReply reply = e.Reply;
        if (reply.Status == IPStatus.Success)
        {
            Console.WriteLine($"Reply from {reply.Address}: time={reply.RoundtripTime}ms");
        }
        else
        {
            Console.WriteLine($"Ping failed: {reply.Status}");
        }
    }
}

このコードでは、Pingを送信する際に、バイトサイズやタイムアウト時間を設定できる。これにより、より柔軟にPingを送信することが可能となる。

他の使い方

また、SendPingAsyncメソッドを使用すれば、非同期でPingを送信して、ネットワークの応答を素早く取得することができる。この方法は、特にローカルエリアネットワーク内の複数のデバイスに対して同時にPingを送る際に役立つ。

C#
using System;
using System.Net.NetworkInformation;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        string[] ipAddresses = new string[]
        {
            "8.8.8.8",
            "8.8.4.4",
            "192.168.1.1",
            "192.168.10.1"
        };

        // 各IPアドレスに対してPingを送信するタスクを作成
        Task[] pingTasks = new Task[ipAddresses.Length];
        for (int i = 0; i < ipAddresses.Length; i++)
        {
            pingTasks[i] = PingAsync(ipAddresses[i]);
        }

        // 全てのPingタスクが完了するのを待つ
        await Task.WhenAll(pingTasks);
    }

    static async Task PingAsync(string ipAddress)
    {
        using (Ping pingSender = new Ping())
        {
            try
            {
                PingReply reply = await pingSender.SendPingAsync(ipAddress, 1000);
                if (reply.Status == IPStatus.Success)
                {
                    Console.WriteLine($"Reply from {reply.Address}: time={reply.RoundtripTime}ms");
                }
                else
                {
                    Console.WriteLine($"Ping to {ipAddress} failed: {reply.Status}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Ping to {ipAddress} failed with exception: {ex.Message}");
            }
        }
    }
}

このコードでは、8.8.8.8などの指定したリストの各IPアドレスに対して、非同期でPingを送信しています。各IPアドレスに対して応答があるかどうかを確認し、その結果を表示します。これにより、ローカルネットワーク内の複数のデバイスが稼働しているかを素早く確認できます。

このブログを検索

QooQ