【问题标题】:Getting Faster result on Ping in C#在 C# 中获得更快的 Ping 结果
【发布时间】:2013-01-16 15:00:53
【问题描述】:

我正在制作一个工具来使用 .NET 中的“PingReply”类测试与特定主机的连接。我的问题是,如果 ping 结果失败,需要一段时间才能得到结果。它是 LAN 环境,所以我已经可以假设如果连接时间超过 100 毫秒,则连接失败。如果与主机的连接失败,下面的代码显示了 5 秒后的结果,即 5000 毫秒。即使连接失败,我能得到更快的结果吗?

Ping x = new Ping();
PingReply reply = x.Send(IPAddress.Parse("192.168.0.1")); 
if (reply.Status == IPStatus.Success)
{
    //Do something
}

【问题讨论】:

  • 你没有提供你的 ping 对象。
  • 您是否也尝试过使用 Ping 类? msdn.microsoft.com/en-us/library/…
  • 有一个超时例子here
  • 谢谢大家。我解决了。
  • 某些行为将遵循允许超时的 TCP/IP 标准。

标签: c# winforms ping


【解决方案1】:

您可以将超时传递给 Ping.Send() 方法。请检查重载的成员。

【讨论】:

  • 需要注意的是,这个方法总是使用最少 500ms,即使你指定的超时时间低于这个值。
【解决方案2】:

由于我们看不到您的 ping 对象,因此假设您不知道 TIMEOUT。我通常发送一个异步 ping,并将超时设置为 3 秒。

 try
            {
                Ping ping = new Ping();
                ping.PingCompleted += (sender, e) =>
                {
                    if (e.Reply.Status != IPStatus.Success)
                        // Report fail
                    else                    
                       // Report success

                };
                ping.SendAsync(target, 3000, target); // Timeout is 3 seconds here
            }
            catch (Exception)
            {
                return;
            }

【讨论】:

  • 投反对票:请发表评论。
【解决方案3】:

Ping.Send() 有一个带有超时参数的重载:

PingReply reply = x.Send(IPAddress.Parse("192.168.0.1"), 100);

【讨论】:

    【解决方案4】:

    您可以使用异步委托来启动 Ping。异步委托有一个名为 BeginInvoke 的函数,它将启动一个后台线程,该线程将立即返回一个 IAsyncResult。 IAsyncResult 有一个称为 AsyncWaitHandle 的等待处理程序,它有一个称为 WaitOne 的方法,可以为该方法分配等待时间。这将在给定时间(以毫秒为单位)冻结当前线程,在您的情况下为 100,然后您可以使用属性 IsCompleted 来检查线程是否已完成其工作。例如:

    Func<PingReply>  pingDelegate = () => new Ping().Send(IPAddress.Parse("192.168.0.1"));
    
    IAsyncResult result = pingDelegate.BeginInvoke(r => pingDelegate.EndInvoke(r), null);
    
    //wait for thread to complete
    result.AsyncWaitHandle.WaitOne(100);
    
    if (result.IsCompleted)
    {
        //Ping Succeeded do something
        PingReply reply = (PingReply) result;
    
        //Do something with successful reply
    }
    

    【讨论】:

    • 投反对票:请发表评论
    • 他们出于某种原因不发表评论,我也被否决了……您的帖子似乎对我解释得很好,也很详细。为你 +1。
    【解决方案5】:

    我也创建了一个实时主机扫描仪。它使用 ARP 检查计算机是否在线。 ARP 请求比 ping 主机要快得多。 这是我用来检查主机是否可用的代码:

    //You'll need this pinvoke signature as it is not part of the .Net framework
    [DllImport("iphlpapi.dll", ExactSpelling = true)]
    public static extern int SendARP(int DestIP, int SrcIP, 
                                     byte[] pMacAddr, ref uint PhyAddrLen);
    
    //These vars are needed, if the the request was a success 
    //the MAC address of the host is returned in macAddr
    private byte[] macAddr = new byte[6];
    private uint macAddrLen;
    
    //Here you can put the IP that should be checked
    private IPAddress Destination = IPAddress.Parse("127.0.0.1");
    
    //Send Request and check if the host is there
    if (SendARP((int)Destination.Address, 0, macAddr, ref macAddrLen) == 0)
    {
        //SUCCESS! Igor it's alive!
    }
    

    如果您有兴趣 Nmap also uses this technique 扫描可用主机。

    ARP 扫描让 Nmap 及其优化算法负责 ARP 请求。如果它得到响应,Nmap 甚至不需要担心基于 IP 的 ping 数据包,因为它已经知道主机已启动。这使得 ARP 扫描比基于 IP 的扫描更快、更可靠。因此,当扫描 Nmap 检测到的以太网主机位于本地以太网网络时,默认情况下会执行此操作。即使指定了不同的 ping 类型(例如 -PE 或 -PS),Nmap 也会对同一 LAN 上的任何目标使用 ARP。

    这仅适用于当前子网!只要请求机器和目标之间没有路由器,它就可以正常工作。

    ARP 是一种不可路由的协议,因此只能在同一以太网网络上的系统之间使用。 [...] arp-scan 可用于发现本地网络上的 IP 主机。它可以发现所有主机,包括那些阻止所有 IP 流量的主机,例如防火墙和带有入口过滤器的系统。 - Excerpt from NTA-Monitor wiki

    有关 SendARP 功能的更多信息,您可以查看pinvoke.net 文档。

    【讨论】:

      猜你喜欢
      • 2017-02-09
      • 1970-01-01
      • 2020-04-25
      • 2023-03-24
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 2023-03-08
      • 2021-12-06
      相关资源
      最近更新 更多