Сбой .Net 2.0 Ping в долго работающей системе. Windows Ping успешно - PullRequest
1 голос
/ 24 октября 2011

У меня есть приложение .Net 2.0, написанное на C #, которое контролирует другие компьютеры с Windows XP в локальной сети.В некоторых системах после длительного времени безотказной работы (от 40 до 120 дней) .Net Ping может перестать работать.Проверка связи с командной строкой Windows по-прежнему завершается успешно.

Как только произошел этот сбой, кажется, что все. Net Pings не работают.Отдельное приложение .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;
}

Ключевые моменты настройки для этой проблемы:

  • Все ПК подключены к одному и тому же неуправляемому коммутатору
  • Все другие ПК могут использовать один и тот же .Net Ping для связи с проблемной системой.
  • Пинг Windows корректно работает в проблемной системе.
  • Любое приложение .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).

После перезапуска проблемыкомпьютер, запускается .Net Pingдля правильной работы снова

Похоже, что существует проблема с ресурсом некоторого описания.Я не уверен, каким ресурсом это может быть.

Я читал о проблемах с асинхронными Ping и .Net 2.0.Это синхронный пинг, и, насколько я могу судить, это не влияет.

Я ищу:

  • Профилактика проблемы, в первую очередь
  • Предложения по отладке удаленной системы в случае ее сбоя (производственная система, Windows XP SP3, инструменты разработчика не установлены)
  • Мониторинг ресурсов для определения, какая из них выходит из строя.

Предупреждения:

  • Регулярно перезагружать проблемную систему в настоящее время не вариант.
  • Обновление до последней версии .Net Framework в настоящее время недоступно.
  • Изменение программного обеспечения, чтобы больше не использовать. Net Ping - вариант, но я все еще хотел бы знать, что происходит.

Ответы [ 2 ]

1 голос
/ 21 ноября 2011

В той же системе было запущено другое приложение, которое потребляло огромное количество (> 100 МБ) байт невыгружаемого пула .Это произошло в течение нескольких недель.

Это было определено путем просмотра счетчиков производительности для всей системы.Выделены следующие:

  • Память, пул невыгружаемых байтов (который охватывает весь компьютер)
  • Процесс, _Total, пул невыгружаемых байтов (который, кажется, охватывает весь запущенный процесс)
  • Процесс, байты невыгружаемого пула для каждого запущенного процесса в системе.

Байты невыгружаемого пула выделяются как очень большое число, все они сосредоточены в одном приложении

Перезапуск другого приложения привел к тому, что использование памяти в невыгружаемом пуле вернулось к гораздо более низкому значению.Пинг успешно завершен.Похоже, что нехватка памяти в невыгружаемом пуле вызывает сбой проверки связи.

Информация о пуле Не выгружаемые байты можно найти на странице Расширение границ Windows: выгружаемый и невыгружаемый пул .Когда в системе заканчиваются байты Nonpaged, во многих распределениях ресурсов может быть отказано, что приводит к чрезвычайно нестабильной системе.

Очень необычная проблема.Резолюция не имела ничего общего с источником Ping.

0 голосов
/ 24 октября 2011

Ваш код не сильно отличается от того, что я использовал для механизма проверки пинга.У меня никогда не было проблем, но кажется, что ваша вообще не входит в сферу применения.Я бы сказал, что либо драйвер сетевой карты глючит, либо стек 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();
        }
    }
...