Правильный способ сканирования диапазона IP-адресов - PullRequest
4 голосов
/ 17 ноября 2009

Учитывая диапазон IP-адресов, введенных пользователем (различными способами), я хочу определить, на каком из этих компьютеров работает программное обеспечение, с которым я могу общаться.

Вот основной процесс:

  1. Пингуйте эти адреса, чтобы найти доступные машины

  2. Подключение к известной розетке на доступных машинах

  3. Отправка сообщения на успешно установленные сокеты

  4. Сравните ответ с ожидаемым ответом

Шаги 2-4 для меня прямолинейны. Каков наилучший способ реализовать первый шаг в .NET?

Я смотрю на класс System.Net.NetworkInformation.Ping. Должен ли я пинговать несколько адресов одновременно, чтобы ускорить процесс? Если я пингую один адрес за раз с большим таймаутом, это может занять вечность. Но с небольшим таймаутом я могу пропустить некоторые машины, которые доступны.

Иногда, когда я знаю, что адрес указывает на активную машину, кажется, что эхо-запросы не выполняются. Нужно ли дважды пинговать в случае отклонения запроса?

В довершение всего, когда я сканирую большие коллекции адресов с отключенным сетевым кабелем, Ping генерирует исключение NullReferenceException в FreeUnmanagedResources (). !

Какие-нибудь указатели на лучший подход к сканированию диапазона IP-адресов, как это?

Ответы [ 4 ]

4 голосов
/ 18 ноября 2009

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

Если вы знаете машины, которые вы будете подключать для ответа на эхо-запросы, класс ping работает достаточно хорошо. Он отправляет только 1 пакет, поэтому ping более одного раза в случае сброса. Кроме того, по моему опыту, класс ping будет часто генерировать исключение вместо возврата объекта PingReply, если хост недоступен.

Это моя предложенная реализация:

public bool
   Ping (string host, int attempts, int timeout)
   {
      System.Net.NetworkInformation.Ping  ping = 
                                       new System.Net.NetworkInformation.Ping ();

      System.Net.NetworkInformation.PingReply  pingReply;

      for (int i = 0; i < attempts; i++)
      {
         try
         {
            pingReply = ping.Send (host, timeout); 

            // If there is a successful ping then return true.
            if (pingReply != null &&
                pingReply.Status == System.Net.NetworkInformation.IPStatus.Success)
               return true;
         }
         catch
         {
            // Do nothing and let it try again until the attempts are exausted.
            // Exceptions are thrown for normal ping failurs like address lookup
            // failed.  For this reason we are supressing errors.
         }
      }

      // Return false if we can't successfully ping the server after several attempts.
      return false;
   }
4 голосов
/ 17 ноября 2009

Не забывайте головную боль людей, которые будут отрицать пинг в своих правилах брандмауэра.

Единственное, что я могу предложить, это вопрос: нужно ли делать №1?

Разве вы не можете просто попытаться подключиться к этому известному сокету? Успешное подключение к этой розетке убивает двух зайцев одним выстрелом: да, хост там / жив, и да, известная розетка открыта.

Этот тип ситуации хорошо подходит для многопоточности, запускает его в другом потоке и ждет, пока он вернется с ответом ...

0 голосов
/ 04 октября 2010

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

Вы можете использовать nmap -sP 192.168.2.1-200 для сканирования с 192.168.2.0 до 192.168.2.255

0 голосов
/ 18 марта 2010

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

Вряд ли когда-либо есть причина "обнаруживать компьютеры в сети", пусть они вместо этого говорят с вами, когда и если захотят.

...