четверг, 13 ноября 2008 г.

Программа для отображения состояния коннекта

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

Так что приходилось располагать окошки так, чтобы видеть консоль с ping -t google.ru. А потом мне пришла в голову светлая идея написать программу для отображения состояния пинга в трее. В качестве языка реализации был выбран C#, дабы не заморачиваться.

Сначала создаем проект вида Windows Application. На главную форму можно не кидать никакие элементы управления, все равно не понадобятся. Зато в ресурсы надо добавить два каких-нибудь значка, один из которых будет называться Ping и обозначать коннект, а второй - Noping и отсутствие коннекта. Вот код формы:

namespace Pinger
{
  public partial class PingForm : Form
  {
    /// <summary>Иконка, обозначающая коннект</summary>
    private static NotifyIcon pingIcon;
    /// <summary>Иконка, обозначающая отсутствие коннекта</summary>
    private static NotifyIcon nopingIcon;

    /// <summary>true, если есть коннект, false иначе</summary>
    private static bool pingState;
    public static bool PingState
    {
      get { return pingState; }
      set
      {
        if (pingState != value) // если значение pingState изменилось
        {
          pingState = value;
          
          // переключаем иконки в трее
          NotifyIcon currentIcon = pingState ? pingIcon : nopingIcon;
          pingIcon.Visible = pingState;
          nopingIcon.Visible = !pingState;
          
          // показываем подсказку
          currentIcon.ShowBalloonTip(2000);
        }
      }
    }

    /// <summary>
    /// Функция, отправляющая пинг
    /// </summary>
    private void MakePing()
    {
      Ping pingSender = new Ping();

      // Добавляем обработчик для события окончания пинга
      pingSender.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
      
      // инициализируем буфер с данными
      string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
      byte[] buffer = Encoding.ASCII.GetBytes(data);

      // куда посылаем пинг
      string who = "google.ru";

      // сколько ждем
      int timeout = 3000;

      AutoResetEvent waiter = new AutoResetEvent(false);
      PingOptions options = new PingOptions(64, true);

      while (true)
      {
        try
        {
          // собственно посыл пинга
          pingSender.SendAsync(who, timeout, buffer, options, waiter);
        }
        catch (Exception e)
        {
        }

        Thread.Sleep(timeout);
      }
    }

    /// <summary>
    /// Конструктор формы
    /// </summary>
    public PingForm()
    {
      InitializeComponent();

      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PingForm));

      // читаем из ресурсов иконки
      pingIcon = new NotifyIcon();
      pingIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("Ping")));
      pingIcon.BalloonTipText = "Ping is OK";
      pingIcon.BalloonTipTitle = "Pinger";
      pingIcon.BalloonTipIcon = ToolTipIcon.Info;

      nopingIcon = new NotifyIcon();
      nopingIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("Noping")));
      nopingIcon.BalloonTipText = "No Ping";
      nopingIcon.BalloonTipTitle = "Pinger";
      nopingIcon.BalloonTipIcon = ToolTipIcon.Warning;

      // значение по умолчанию
      PingState = true;

      // запускаем функцию MakePing в отдельном потоке
      Thread t = new Thread(new ThreadStart(MakePing));
      t.Start();
    }

    /// <summary>
    /// Обработка результата пинга
    /// </summary>
    public static void PingCompletedCallback(object sender, PingCompletedEventArgs e)
    {
      // пинг считается правильным, если не возникло ошибок и пришел ответ Success
      PingState = e.Error == null && e.Reply.Status == IPStatus.Success;
    }
  }
}

Вот, что получилось:

Появился коннект:

Есть коннект

Пропал коннект:

Нет коннекта

Я лично сейчас смотрю и очень радуюсь :) Правда, код для закрытия я поленилась писать, и закрыть программу можно только, отстрелив процесс в Task Manager.

Ссылки

10 комментариев:

Yadovit комментирует...

Всё гениальное - просто! :)
На самом деле хорошая идея.

Kumrio комментирует...

можно с Вами как то связаться? есть несколько вопросов

darja комментирует...

2 kumrio
Жаббер pragma@jabber.ru

ckopn комментирует...

Маленькая программка улучшающая жизнь.

Анонимный комментирует...

Изобретаешь nagios? :)

dsb

darja комментирует...

to dsb:
Неа. Маюсь дурью в отсутствие коннекта :)

casufi комментирует...

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

darja комментирует...

2 casufi:
Проверять коннекшен? Да, можно и так. Даже, возможно, было бы правильнее.
А насчет настроек... Честно говоря, мне лень :) Хватает и такого функционала.

.sid комментирует...

А ведь грустно. Более под виндой никак это и не решишь. Хорошо что в линуксе есть консоль и mtr :)

Анонимный комментирует...

12 метров кушает однако : )