在C#中使用ping

121

当我用Windows Ping一个远程系统时,它会显示没有回复,但是当我使用C#进行ping时,它会显示成功。Windows是正确的,设备未连接。为什么我的代码能够在Windows无法ping通时成功ping通?

这是我的代码:

Ping p1 = new Ping();
PingReply PR = p1.Send("192.168.2.18");
// check when the ping is not success
while (!PR.Status.ToString().Equals("Success"))
{
    Console.WriteLine(PR.Status.ToString());
    PR = p1.Send("192.168.2.18");
}
// check after the ping is n success
while (PR.Status.ToString().Equals("Success"))
{
    Console.WriteLine(PR.Status.ToString());
    PR = p1.Send("192.168.2.18");
}

5
点击以下链接查看本页底部发布的示例:http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx 或者 https://dev59.com/23M_5IYBdhLWcg3wq1CF。 - MethodMan
12
你应该将 PR.Status 与 IPStatus.Success 进行比较,字符串比较在这种情况下不是正确的工具。 - Sam Axe
在执行ping之后,一些PingReply属性的值是什么(例如PR.AddressPR.RoundtripTimePR.reply.Buffer.LengthPR.Options.Ttl)?同时,请确保你的代码中使用的是正确的IP地址,而不是测试IP地址。 - Jon Senchyna
Jon Senchyna:我没有设置它们,而且我确定我的 IP 是正确的。 - Black Star
在我的情况下,如果“启用Visual Studio托管进程”(位置为==>>项目->属性->调试)被禁用,则ping方法可能无法工作。请尝试! - steve
5个回答

268
using System.Net.NetworkInformation;    

public static bool PingHost(string nameOrAddress)
{
    bool pingable = false;
    Ping pinger = null;

    try
    {
        pinger = new Ping();
        PingReply reply = pinger.Send(nameOrAddress);
        pingable = reply.Status == IPStatus.Success;
    }
    catch (PingException)
    {
        // Discard PingExceptions and return false;
    }
    finally
    {
        if (pinger != null)
        {
            pinger.Dispose();
        }
    }

    return pingable;
}

19
这是仅包含代码的答案。我猜测它实现了正确的比较并展示了如何处理可能出现的异常。您能否说明相对于问题中的代码,为什么这是正确的代码? 这是仅包含代码的回答,无法提供更多信息来解释为什么这个代码是正确的,但可以确认它实现了正确的比较,并且使用适当的异常处理方式。 - Maarten Bodewes
13
不知道有多少人通过复制粘贴来使用这个答案 :/ 至少需要使用 using (var pinger = new Ping()) { .. },而早期返回语句是否邪恶? - Peter Schneider
4
如果try/catch/finally被正确使用,就没有必要用using包装Ping实例了。二者只能选择其一而不能同时使用。请参阅https://dev59.com/_HVC5IYBdhLWcg3wfhGL。 - JamieSee
10
虽然那也许是真的,但使用“using”更简洁,而且在这种情况下更受推荐。 - Kelly Elton
我个人赞同使用using语句,但你仍然需要捕获任何异常。 - SteveB
1
展示try-catch块并在'try'块之外声明变量以便立即窗口可以看到它们(如果您在'catch'处设置断点),这将获得两个赞成票,但由于未实际处理异常,将获得一个反对票。 - B H

53
使用C#中的ping方法可以通过使用Ping.Send(System.Net.IPAddress)方法来实现,该方法会向提供的(有效)IP地址或URL发送ping请求,并获取一个响应,称为Internet Control Message Protocol (ICMP) Packet。该数据包包含20字节的头部,其中包含从接收ping请求的服务器返回的响应数据。.Net框架中的System.Net.NetworkInformation命名空间包含一个名为PingReply的类,该类具有用于翻译ICMP响应并提供关于被ping的服务器的有用信息的属性,例如:
  • IPStatus: 获取发送Internet控制消息协议(ICMP)回显应答的主机地址。
  • IPAddress: 获取发送Internet控制消息协议(ICMP)回显请求并接收相应的ICMP回显应答消息所需的毫秒数。
  • RoundtripTime (System.Int64): 获取用于将回复传输到Internet控制消息协议(ICMP)回显请求的选项。
  • PingOptions (System.Byte[]): 获取在Internet控制消息协议(ICMP)回显应答消息中接收的数据缓冲区。
以下是一个简单的示例,使用 WinForms 来演示 c# 中 ping 的工作原理。通过在 textBox1 中提供有效的 IP 地址并点击 button1,我们创建了 Ping 类的实例、一个本地变量 PingReply 和一个字符串来存储 IP 或 URL 地址。我们将 PingReply 分配给 ping 的 Send 方法,然后通过比较回复的状态和属性 IPAddress.Success 的状态来检查请求是否成功。最后,我们从 PingReply 提取需要显示给用户的信息,如上所述。
    using System;
    using System.Net.NetworkInformation;
    using System.Windows.Forms;

    namespace PingTest1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            private void button1_Click(object sender, EventArgs e)
            {
                Ping p = new Ping();
                PingReply r;
                string s;
                s = textBox1.Text;
                r = p.Send(s);

                if (r.Status == IPStatus.Success)
                {
                    lblResult.Text = "Ping to " + s.ToString() + "[" + r.Address.ToString() + "]" + " Successful"
                       + " Response delay = " + r.RoundtripTime.ToString() + " ms" + "\n";
                }
            }

            private void textBox1_Validated(object sender, EventArgs e)
            {
                if (string.IsNullOrWhiteSpace(textBox1.Text) || textBox1.Text == "")
                {
                    MessageBox.Show("Please use valid IP or web address!!");
                }
            }
        }
    }

10
感谢包含使用参考! - mattpm
1
你不能写几行代码并解释一下吗?这样对于想要理解这段代码的人来说是没有用的。 - Hille
4
当然,@Hille。我几年前很快写了这个答案,现在我会编辑并添加适当的描述。 - Ashraf Sada
应该在使用后释放Ping using (Ping p = new Ping()) { ... } - marsh-wiggle

-1
private async void Ping_Click(object sender, RoutedEventArgs e)
{
    Ping pingSender = new Ping();
    string host = @"stackoverflow.com";
    await Task.Run(() =>{
         PingReply reply = pingSender.Send(host);
         if (reply.Status == IPStatus.Success)
         {
            Console.WriteLine("Address: {0}", reply.Address.ToString());
            Console.WriteLine("RoundTrip time: {0}", reply.RoundtripTime);
            Console.WriteLine("Time to live: {0}", reply.Options.Ttl);
            Console.WriteLine("Don't fragment: {0}", reply.Options.DontFragment);
            Console.WriteLine("Buffer size: {0}", reply.Buffer.Length);
         }
         else
         {
            Console.WriteLine("Address: {0}", reply.Status);
         }
   });           
}

-2
Imports System.Net.NetworkInformation


Public Function PingHost(ByVal nameOrAddress As String) As Boolean
    Dim pingable As Boolean = False
    Dim pinger As Ping
    Dim lPingReply As PingReply

    Try
        pinger = New Ping()
        lPingReply = pinger.Send(nameOrAddress)
        MessageBox.Show(lPingReply.Status)
        If lPingReply.Status = IPStatus.Success Then

            pingable = True
        Else
            pingable = False
        End If


    Catch PingException As Exception
        pingable = False
    End Try
    Return pingable
End Function

4
这段代码是使用Visual Basic编写的,但问题需要使用C#语言。 - GrantByrne

-12
private void button26_Click(object sender, EventArgs e)
{
    System.Diagnostics.ProcessStartInfo proc = new System.Diagnostics.ProcessStartInfo();
    proc.FileName = @"C:\windows\system32\cmd.exe";
    proc.Arguments = "/c ping -t " + tx1.Text + " ";
    System.Diagnostics.Process.Start(proc);
    tx1.Focus();
}

private void button27_Click(object sender, EventArgs e)
{
    System.Diagnostics.ProcessStartInfo proc = new System.Diagnostics.ProcessStartInfo();
    proc.FileName = @"C:\windows\system32\cmd.exe";
    proc.Arguments = "/c ping  " + tx2.Text + " ";
    System.Diagnostics.Process.Start(proc);
    tx2.Focus();
}

3
你不能写几行代码解释一下吗?因为这对于想要理解这段代码的人来说并不有用... - Hille
所提供的代码完全不符合DRY原则 - greybeard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接