 |
|
Асинхронный пинг сети и возврат пингующихся 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();
}
Спасибо!
|
Небольшое замечание:
Код:
System.Net.IPAddress ip = System.Net.Dns.GetHostByName(host).AddressList[0];
Если на машине 2 и более сетевых, какая нибудь wmware со своими сетевыми, то тут опрашивается только первая сетевая. Если она будет недоступна, то и пинг не пройдет.
Я бы сделал так: Кидал результаты не в RichTextBox, а в DataGridView, предварительно сделав там 2 столбца: PC и Result. Соответственно, добавлял бы в список машину и результат пинга.
А в самом конце, после осмотра, пробежался циклом foreach по списке и удалил строки, где нет ответа от сервера.
|
Цитата:
Цитата Delirium
Если на машине 2 и более сетевых, какая нибудь wmware со своими сетевыми, то тут опрашивается только первая сетевая. Если она будет недоступна, то и пинг не пройдет. »
|
Подскажите каким методом это можно вылечить?
Цитата:
Цитата Delirium
Соответственно, добавлял бы в список машину и результат пинга. »
|
Вот результат пинга я и не понимаю как поймать... Подскажите пожалуйста
|
Подсказали решение на другом форуме, может кому пригодиться:
Код:
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();
}
|
Цитата:
Цитата 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.
© OSzone.net 2001-