c# ping 很多主机的最佳方法

c# best way to ping lot of hosts

我尝试 运行 CMD 并从那里获得了 ping 信息:

    ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
    cmdStartInfo.FileName = @"cmd";
    cmdStartInfo.RedirectStandardOutput = true;
    cmdStartInfo.RedirectStandardError = true;
    cmdStartInfo.RedirectStandardInput = true;
    cmdStartInfo.UseShellExecute = false;
    cmdStartInfo.CreateNoWindow = true;

    Process cmd = new Process();
    cmd.StartInfo = cmdStartInfo;
    cmd.ErrorDataReceived += DataReceived;
    cmd.OutputDataReceived += DataReceived;
    cmd.EnableRaisingEvents = true;
    cmd.Start();
    cmd.BeginOutputReadLine();
    cmd.BeginErrorReadLine();

    cmd.StandardInput.WriteLine("ping www.bing.com");
    cmd.StandardInput.WriteLine("exit");

    System.Threading.Thread.Sleep(4000);
    cmd.WaitForExit();

有更好的方法吗?

首先确定你确实需要打开一个shell来处理命令。在您的示例中,直接 运行 ping 会更简单,例如,

ProcessStartInfo cmdStartInfo = new ProcessStartInfo()
{
    FileName = "ping",
    Arguments = "www.bing.com",
    RedirectStandardOutput = true,
    CreateNoWindow = true,
    UseShellExecute = false
};

Process proc = Process.Start(cmdStartInfo);
string reply = proc.StandardOutput.ReadToEnd();

其中 ReadToEnd 将等到进程完成后再返回,为您提供 ping 的全部输出。 ReadToEnd 也适用于您的示例,而不是 Sleep.

我假设这只是一个人为的例子,但如果不是,您不需要像这样使用 ping - .net 提供了更容易使用的 ping class。例如。

private static void Ping(string address = "bing.com", int iterations = 4)
{
    Ping ping = new Ping();
    var hostEntry = Dns.GetHostEntry(address);

    byte[] buffer = new byte[32];
    new Random().NextBytes(buffer);

    Console.WriteLine("Pinging {0} [{1}] with {2} bytes of data:", hostEntry.HostName, hostEntry.AddressList[0], buffer.Length);

    for (int i = 0; i < iterations; i++)
    {
        PingReply reply = ping.Send(address, 1000, buffer);    
        Console.WriteLine("Reply from {0}: bytes={1}, time={2}ms, TTL={3}", reply.Address, reply.Buffer.Length, reply.RoundtripTime, reply.Options.Ttl);
    }
}

编辑:为了避免挂起,您可以这样写。

static void Main()
{
    Task<string> pingReply = RunCommand("ping", "bing.com");

    Console.WriteLine("I am waiting for ping to complete and could be doing something useful");

    pingReply.Wait();

    Console.WriteLine(pingReply.Result);
    Console.ReadKey();
}

public static Task<string> RunCommand(string command, string args)
{
    ProcessStartInfo cmdStartInfo = new ProcessStartInfo()
    {
        FileName = command,
        Arguments = args,
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        UseShellExecute = false
    };

    Process proc = Process.Start(cmdStartInfo);        
    Task<string> readCommand = proc.StandardOutput.ReadToEndAsync();

    return readCommand;
}