. net 2.0在长时间运行的系统中Ping失败Windows Ping成功

本文关键字:Ping 失败 Windows 成功 系统 长时间 运行 net | 更新日期: 2023-09-27 18:12:07

我有一个用c#编写的。net 2.0应用程序,它可以监视本地局域网上的其他Windows XP计算机。在某些系统上,经过长时间的正常运行(40到120天)后,. net Ping可能会失败。Windows命令提示符ping仍然成功

一旦发生此失败,似乎所有. net ping都失败。使用类似代码的另一个。net应用程序也会失败。

下面是一个示例代码:

internal static bool canPingHost(string host)
{
    bool success = false;
    const int PING_TIMEOUT_MS = 1000;
    try
    {
       using (Ping p = new Ping())
       {
            PingReply pr = p.Send(host, PING_TIMEOUT_MS);
            if (pr.Status == IPStatus.Success)
            {
                success = true;
            }
        }
    }
    catch
    {                
    }
    return success;
}

关于这个问题的设置要点:

  • 所有pc都插入到同一个非管理交换机
  • 所有其他pc可以使用相同的。net Ping与问题系统对话。
  • Windows ping在问题系统上工作正常。
  • 任何。net 2.0应用程序在出现问题的系统上尝试失败。
  • 数据库与问题系统之间的操作也可以工作(TCP连接)
  • 停止和启动应用程序并不能解决问题系统上的问题。

当这个系统失败时,我运行了另一个带有进一步调试信息的应用程序。

static string doping(IPAddress IP)
{
    int PING_TIMEOUT_MS = 3000;
    string rv = IP.ToString();
    using (Ping p = new Ping())
    {
        bool success = false;
        PingReply pr = null;
        try
        {
            pr = p.Send(IP, PING_TIMEOUT_MS);
            success = pr.Status == IPStatus.Success;
        }
        catch (Exception ex)
        {
            rv = rv +" [ " +ex.Message + " ] ";
        }
        if (pr != null)
        {
            if (success)
            {
                rv = rv + " yes " + pr.RoundtripTime.ToString();
            }
            else
            {
                rv = rv + " no " + pr.Status.ToString();
            }
        }
        else
        {
            rv = rv + " no (fail) ";
        }
    }
    return rv;
}

程序的输出为192.168.0.2 no 1450
PingReply状态变量返回1450,这似乎没有在IPStatus (PingReply.Status) enum中定义。

重新启动问题计算机后,.Net Ping又开始正常工作了

似乎有某种描述的资源问题。我不确定它可能是哪个资源。

我读过关于异步ping和。net 2.0的问题。这是一个同步ping,据我所知它没有受到影响。

我在找:

  • 首先预防问题
  • 远程系统故障时的调试建议(生产系统,Windows XP SP3,未安装开发工具)
  • 监视资源以确定哪个资源失败。

事项:

  • 定期重新启动问题系统目前不是一个选项。
  • 升级到最新版本的。net框架目前不支持。
  • 改变软件不再使用。net Ping是一个选项,但我仍然想知道发生了什么。

. net 2.0在长时间运行的系统中Ping失败Windows Ping成功

在同一系统上运行的另一个应用程序正在消耗大量(> 100 MB)的池非分页字节。这件事持续了几个星期。

这是通过查看整个系统的性能计数器来确定的。其中比较突出的是:

  • 内存,池非分页字节(覆盖整个计算机)
  • Process, _Total, Pool nonpage Bytes(似乎覆盖了所有正在运行的进程)
  • 进程,为系统中每个正在运行的进程池非分页字节。

Pool非分页字节数目非常大,全部集中在一个应用程序中

重新启动另一个应用程序导致非分页池内存使用率返回到一个更低的值。Ping随即顺利完成。缺少非分页池内存似乎是导致Ping失败的原因。

关于池非分页字节的信息可以在推入Windows的极限:分页和非分页池中找到。当系统用完非分页字节时,许多资源分配可能会被拒绝,从而导致系统非常不稳定。

非常不寻常的问题。该决议与Ping源没有任何直接关系。

您的代码看起来与我用于ping检查机制的代码没有太大不同。我从来没有遇到过这样的问题,但您的问题似乎完全超出了应用程序领域。我想要么是有bug的网卡驱动程序,要么是IP栈损坏了。

    private static void Main()
    {
        using (var ping = new Ping())
        using (var waiter = new EventWaitHandle(false, EventResetMode.ManualReset))
        {
            var options = new PingOptions { DontFragment = true };
            var now = DateTime.Now;
            var data = now.ToLongDateString() + " " + now.ToLongTimeString();
            var buffer = Encoding.ASCII.GetBytes(data);
            const int Timeout = 120;
            ping.PingCompleted += PingCompleted;
            ping.SendAsync("www.speedtest.net", Timeout, buffer, options, waiter);
            waiter.WaitOne();
        }
        Console.ReadLine();
    }
    /// <summary>
    /// Handles the Ping Completed event.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.Net.NetworkInformation.PingCompletedEventArgs"/> instance containing
    /// the event data.</param>
    private static void PingCompleted(object sender, PingCompletedEventArgs e)
    {
        if (e.Reply.Status == IPStatus.Success)
        {
            Console.WriteLine("Address: {0}", e.Reply.Address);
            Console.WriteLine("RoundTrip time: {0}", e.Reply.RoundtripTime);
            Console.WriteLine("Time to live: {0}", e.Reply.Options.Ttl);
            Console.WriteLine("Don't fragment: {0}", e.Reply.Options.DontFragment);
            Console.WriteLine("Buffer size: {0}", e.Reply.Buffer.Length);
            Console.WriteLine("Buffer: {0}", Encoding.ASCII.GetString(e.Reply.Buffer));
        }
        else if (e.Error != null)
        {
            Console.WriteLine(e.Error);
        }
        var waitHandle = e.UserState as EventWaitHandle;
        if (waitHandle != null)
        {
            waitHandle.Set();
        }
    }