首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 實作 Ping 功能:透過 Process 執行命令列並解析回應

     編輯:關於C#

實作思路

利用 System.Diagnostics.Process 啟動 cmd.exe,重導向標準輸入/輸出/錯誤流,寫入 ping 指令並讀取輸出結果。此法不需 P/Invoke 呼叫 ICMP API,相容性佳。

完整程式碼

using System;
using System.Diagnostics;
using System.Text;

public class PingHelper
{
    /// 
    /// 執行 ping 並回傳原始輸出文字
    /// 
    public static string Ping(string ipAddress, int count = 1, int timeoutMs = 3000)
    {
        var psi = new ProcessStartInfo
        {
            FileName = "cmd.exe",
            UseShellExecute = false,
            RedirectStandardInput = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true,
            StandardOutputEncoding = Encoding.GetEncoding(950), // 繁中系統預設 Big5 (CP950)
            StandardErrorEncoding = Encoding.GetEncoding(950)
        };

        using (var proc = Process.Start(psi))
        {
            // 寫入 ping 指令:-n 指定次數,-w 指定超時(ms)
            proc.StandardInput.WriteLine($"ping -n {count} -w {timeoutMs} {ipAddress}");
            proc.StandardInput.WriteLine("exit");
            proc.StandardInput.Close();

            string output = proc.StandardOutput.ReadToEnd();
            string error = proc.StandardError.ReadToEnd();

            proc.WaitForExit(5000); // 保護性等待

            if (!string.IsNullOrEmpty(error))
                return $"ERROR: {error}";

            return output;
        }
    }

    /// 
    /// 簡易判斷是否可達
    /// 
    public static bool IsReachable(string ipAddress)
    {
        string result = Ping(ipAddress);
        // 簡單關鍵字判斷,實務建議用 Regex 擷取 "TTL=" 或 "Reply from"
        return result.Contains("TTL=") || result.Contains("Reply from") || result.Contains("回覆");
    }
}

使用範例

string ip = "8.8.8.8";
string raw = PingHelper.Ping(ip, count: 3);
Console.WriteLine(raw);

if (PingHelper.IsReachable(ip))
    Console.WriteLine($"{ip} 可連線");
else
    Console.WriteLine($"{ip} 不可連線");

進階:解析關鍵指標

public class PingResult
{
    public bool Success { get; set; }
    public int Sent { get; set; }
    public int Received { get; set; }
    public int Lost { get; set; }
    public int MinMs { get; set; }
    public int MaxMs { get; set; }
    public int AvgMs { get; set; }
}

public static PingResult ParsePingOutput(string output)
{
    var result = new PingResult();
    // 以正規表示式擷取統計行,例:
    // "已傳送 = 3,已收到 = 3,失敗 = 0 (0% 遺失),"
    // "最短 = 5ms,最長 = 8ms,平均 = 6ms"
    var statsMatch = Regex.Match(output, @"已傳送\s*=\s*(\d+).*?已收到\s*=\s*(\d+).*?失敗\s*=\s*(\d+)");
    if (statsMatch.Success)
    {
        result.Sent = int.Parse(statsMatch.Groups[1].Value);
        result.Received = int.Parse(statsMatch.Groups[2].Value);
        result.Lost = int.Parse(statsMatch.Groups[3].Value);
        result.Success = result.Received > 0;
    }

    var timeMatch = Regex.Match(output, @"最短\s*=\s*(\d+)ms.*?最長\s*=\s*(\d+)ms.*?平均\s*=\s*(\d+)ms");
    if (timeMatch.Success)
    {
        result.MinMs = int.Parse(timeMatch.Groups[1].Value);
        result.MaxMs = int.Parse(timeMatch.Groups[2].Value);
        result.AvgMs = int.Parse(timeMatch.Groups[3].Value);
    }
    return result;
}

替代方案對照

方案優點缺點
Process + ping.exe無需管理員權限、跨平台(Linux/macOS 亦有 ping)、支援主機名解析啟動進程開銷大、解析輸出需處理多語系
System.Net.NetworkInformation.PingManaged API、效能佳、強型別回傳、支援非同步需 .NET 2.0+、部分舊版 OS 需管理員權限
ICMP DLL (IcmpSendEcho)底層控制最細P/Invoke 複雜、需管理員權限、易出錯

建議

現代 .NET 專案請直接使用 System.Net.NetworkInformation.Ping,僅在舊版框架、特殊權限限制或需相容非 Windows 平台時才考慮 Process 方案。

// 現代寫法(.NET Core / .NET 5+ / .NET Framework 2.0+)
using System.Net.NetworkInformation;

var ping = new Ping();
var reply = ping.Send("8.8.8.8", 3000);
if (reply.Status == IPStatus.Success)
    Console.WriteLine($"RTT: {reply.RoundtripTime} ms");
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved