Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Асинхронный пинг сети и возврат пингующихся ip адресов (http://forum.oszone.net/showthread.php?t=230308)

pogo 14-03-2012 09:26 1878869

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

Код:

private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //создаем класс управления событиями в потоке
                AutoResetEvent waiter = new AutoResetEvent(false);
                //записываем в массив байт сконвертированную в байтовый массив строку для отправки в пинг запросе
                byte[] buffer = Encoding.ASCII.GetBytes("test ping");
                //получаем имя хоста текущей машины
                string host = System.Net.Dns.GetHostName();
                //создаем список для адресов удаленных машин типа string
                List<string> serversList = new List<string>();
                //получаем ip машины по имени хоста
                System.Net.IPAddress ip = System.Net.Dns.GetHostByName(host).AddressList[0];
                log.Info("ip: " + ip);
                //разделяем ip машины на 4 составных части
                string[] ipParts = ip.ToString().Split('.');
                //создаем массив строк для записи туда всех 254 ip для их последующего пингования
                string[] ips = new string[254];
                //для каждого из последнего элемента начиная с 1 заканчивая 254
                for (int i = 1; i < 255; i++)
                {
                    //записываем в массив строк нужный ip для сканирования, собирая его из элементов, последний заменяя на текущее значение переменной i
                    ips[i - 1] = ipParts[0] + '.' + ipParts[1] + '.' + ipParts[2] + '.' + i.ToString();
                }
                //для каждого элемента из массива ip
                foreach (string ipToScan in ips)
                {
                    //пишем его в список адресов
                    serversList.Add(ipToScan);
                    log.Info("serverList: " + ipToScan);
                }
 
                //вообще все начиная с цикла for и до этого момента можно заменить так:
                //for (int i = 1; i < 255; i++)
                //{
                //              serversList.Add(ipParts[0] + '.' + ipParts[1] + '.' + ipParts[2] + '.' + i.ToString());
                //}
                //следующая строка не нужна, я ее закоментирую
                //object syncLock = new object();
                //для каждого элемента из списка адресов
                foreach (string server in serversList)
                {
                    //создаем класс пинг
                    Ping ping = new Ping();
                    //указываем на метод, который будет выполняться в результате получения ответа на асинхронный запрос пинга
                    ping.PingCompleted += new PingCompletedEventHandler(p_PingCompleted);
                    //выставляем опции для пинга (непринципиально)
                    PingOptions options = new PingOptions(64, true);
                    //посылаем асинхронный пинг на адрес с таймаутом 500мс, в нем передаем массив байт сконвертированных их строки в начале кода, используем при передаче указанные опции, после обращаемся к классу управления событиями
                    ping.SendAsync(IPAddress.Parse(server), 500, buffer, options, waiter);
                }
                //очищаем элемент на форму куда будут выводиться все успешные ипы.
                richTextBox1.Clear();
            }
            catch (Exception ex)
            {
                log.Info("Ошибка");
                log.Warn(ex.Message);
                log.Debug(ex.Message);
                log.Error(ex.Message);
            }
        }
 
                //этот метод вызывается при получении ответа на пинг
        private void p_PingCompleted(object sender, PingCompletedEventArgs e)
        {
                //проверяем не равен ли адрес откуда пришел ответ нулевому. вообще ответ от нулевого ip мы получаем в случае если ответа от запрашиваемого хоста нет (таймаут)
            if (e.Reply.Address.ToString() != "0.0.0.0")
            {
                //если не равен - выводим адрес с которого пришел ответ в текстовое поле на форме и делаем перенос строки
                richTextBox1.Text += e.Reply.Address.ToString() + "\r\n";
                log.Info("IP: " + e.Reply.Address.ToString());
            }
            //передаем событие о завершении выполнения ветки после получения ответа
            ((AutoResetEvent)e.UserState).Set();
        }

Спасибо!

Delirium 15-03-2012 04:11 1879544

Небольшое замечание:
Код:

System.Net.IPAddress ip = System.Net.Dns.GetHostByName(host).AddressList[0];
Если на машине 2 и более сетевых, какая нибудь wmware со своими сетевыми, то тут опрашивается только первая сетевая. Если она будет недоступна, то и пинг не пройдет.

Я бы сделал так: Кидал результаты не в RichTextBox, а в DataGridView, предварительно сделав там 2 столбца: PC и Result. Соответственно, добавлял бы в список машину и результат пинга.
А в самом конце, после осмотра, пробежался циклом foreach по списке и удалил строки, где нет ответа от сервера.

pogo 15-03-2012 09:11 1879598

Цитата:

Цитата Delirium
Если на машине 2 и более сетевых, какая нибудь wmware со своими сетевыми, то тут опрашивается только первая сетевая. Если она будет недоступна, то и пинг не пройдет. »

Подскажите каким методом это можно вылечить?

Цитата:

Цитата Delirium
Соответственно, добавлял бы в список машину и результат пинга. »

Вот результат пинга я и не понимаю как поймать... Подскажите пожалуйста

pogo 15-03-2012 12:40 1879759

Подсказали решение на другом форуме, может кому пригодиться:
Код:

private void p_PingCompleted (object sender, PingCompletedEventArgs e)
{
    if (e.Reply.Status == IPStatus.Success)
    {
        //выводим адрес с которого пришел ответ в текстовое поле на форме и делаем перенос строки
        richTextBox1.Text += e.Reply.Address.ToString() + "\r\n";
        log.Info("IP: " + e.Reply.Address.ToString());
    }
    // Let the main thread resume.
    ((AutoResetEvent)e.UserState).Set();
}


Delirium 16-03-2012 01:36 1880376

Цитата:

Цитата pogo
Цитата Delirium:
Если на машине 2 и более сетевых, какая нибудь wmware со своими сетевыми, то тут опрашивается только первая сетевая. Если она будет недоступна, то и пинг не пройдет. »
Подскажите каким методом это можно вылечить? »

Обходить все адреса циклом foreach:

старый вариант
Код:

System.Net.IPAddress ip = System.Net.Dns.GetHostByName(host).AddressList[0];
а надо бы

Код:

foreach(System.Net.IPAddress ip in System.Net.Dns.GetHostByName(host).AddressList)
{
    //и здесь уже все действия по обработке ip
}



Время: 11:37.

Время: 11:37.
© OSzone.net 2001-