Получение ip устройства при неудачном запросе Ping.SendAsync - C#
Формулировка задачи:
Всем привет! Надеюсь, вы поможете найти решение моей проблемы...
Цели создаваемой программы: 1) ping одного устройства по запросу пользователя; 2) ping группы устройств по таймеру.
Суть проблемы: если использовать обычный Ping.Send программа виснет намертво при множественных запросах пинга и наличии недоступных устройств. Поэтому решила использовать асинхронный пинг
Ping.SendAsync
. Теперь проблема в том, чтоPingReply
, возвращаемый при неудачном пинге содержит нулевые параметры и, соответственно, адрес 0.0.0.0. Как мне в обработчикеpingSender_Complete
получить адрес, который программа пыталась пинговать? Сейчас в коде я использую глобальную переменннуюcurrentUSK
, но в случае группового пинга, когда все результаты появляются с разной задержкой, они, естественно, получают самое последнее значение этой переменной. Можно ли адрес или весь объектUSK
передать в обработчик события? Информации на доступном для меня уровне в интернете не нашла. Подскажите, куда копать?namespace PingUSK { /// <summary> /// Логика взаимодействия для MainWindow.xaml /// </summary> public partial class MainWindow : Window { //глобальные переменные public static String connectStr; FbConnection connection = new FbConnection(connectStr); FbCommand command = new FbCommand(); FbDataAdapter dataAdapter = new FbDataAdapter(); DataTable dt = new DataTable(); List<USK> list_of_USK = new List<USK>(); //поток записи и чтения StreamWriter sw; StreamReader sr; //файл FileInfo aFile; USK currentUSK = new USK(); ObservableCollection<resPing> log = new ObservableCollection<resPing>(); System.Threading.Timer tm; AutoResetEvent resetEvent = new AutoResetEvent(false); public MainWindow() { InitializeComponent(); // получаю список УСК GetUSK(); //заполняю комбобокс значениями из списка УСК foreach (var item in list_of_USK) { comboBox1.Items.Add(item.abonent + " | " + item.ip + " | " + item.address); } comboBox1.SelectedIndex = 0; //создание текстового файла с базой или его открытие aFile = new FileInfo("d:\\PingUSK.txt"); if (aFile.Exists == false) { aFile.Create(); } //чтение из файла, вывод в листбокс sr = aFile.OpenText(); while (!sr.EndOfStream) { try { String str = sr.ReadLine(); String[] mas = str.Split('|'); log.Add(new resPing() { id = Convert.ToInt32(mas[0]), abonent = mas[1], address = mas[2], ip = mas[3], time = Convert.ToInt32(mas[4]), status = mas[5], date = Convert.ToDateTime(mas[6]), buf=Convert.ToInt32(mas[7]), TTL=Convert.ToInt32(mas[8]) }); } catch { } } sr.Close(); dataGrid1.ItemsSource = log; dataGrid1.Items.Refresh(); try { dataGrid1.Items.MoveCurrentToLast(); dataGrid1.ScrollIntoView(dataGrid1.SelectedItem); } catch { } //запуск таймера tm = new System.Threading.Timer(Callback, null, new TimeSpan(0, 1, 0), new TimeSpan(0, 1, 0)); } // процедура, выполняемая при срабатывании таймера (коллективный пинг) private void Callback(object param) { foreach (var item in list_of_USK) { try { Dispatcher.BeginInvoke(DispatcherPriority.Send, (Action<USK>)PingForCircle, item); } catch { } } } // пинг одного устройства (на выбор пользователя) public void JustPing() { Int32 i = comboBox1.SelectedIndex; USK cur = list_of_USK[i]; currentUSK = cur; SendPing(cur); } // массовый пинг public void PingForCircle(USK usk) { currentUSK = usk; SendPing(usk); } private void SendPing(USK _cur) { USK cur = _cur; Ping pingSender = new System.Net.NetworkInformation.Ping(); // событие при завершении пинга pingSender.PingCompleted += new PingCompletedEventHandler(pingSender_Complete); // установки byte[] packetData = Encoding.ASCII.GetBytes("................................"); PingOptions packetOptions = new PingOptions(50, true); pingSender.SendAsync(cur.ip, 2000, packetData, packetOptions, resetEvent); //посылка асинхронного пинга } private void pingSender_Complete(object sender, PingCompletedEventArgs e) { if (e.Cancelled) { ((AutoResetEvent)e.UserState).Set(); } else if (e.Error != null) { MessageBox.Show("An error occured: " + e.Error + "\r\n"); ((AutoResetEvent)e.UserState).Set(); } else { PingReply pingResponse = e.Reply; // вызов процедуры вывода результатов ShowPingResults(pingResponse); } } public void ShowPingResults(PingReply pingResponse) { String adr = pingResponse.Address.ToString(); USK getUSK = new USK(); // поиск уск в списке по ip foreach (var item in list_of_USK) { if (item.ip == adr) { getUSK = item; break; } } //если пинг неудачный... if (pingResponse.RoundtripTime == 0) { log.Add(new resPing() { id = Convert.ToInt32(getUSK.id), abonent = getUSK.abonent, address = getUSK.address, ip = getUSK.ip, time = Convert.ToInt32(pingResponse.RoundtripTime.ToString()), status = pingResponse.Status.ToString(), date = DateTime.Now, buf = pingResponse.Buffer.Length, TTL = 0 }); dataGrid1.Items.Refresh(); dataGrid1.Items.MoveCurrentToLast(); dataGrid1.ScrollIntoView(dataGrid1.SelectedItem); sw = aFile.AppendText(); sw.WriteLine(getUSK.id + "|" + getUSK.abonent + "|" + getUSK.address + "|" + getUSK.ip + "|" + pingResponse.RoundtripTime + "|" + pingResponse.Status + "|" + DateTime.Now + "|" + pingResponse.Buffer.Length + "|" + "0"); sw.Close(); } // если пинг прошел... else { log.Add(new resPing() { id = Convert.ToInt32(getUSK.id), abonent = getUSK.abonent, address = getUSK.address, ip = getUSK.ip, time = Convert.ToInt32(pingResponse.RoundtripTime.ToString()), status = pingResponse.Status.ToString(), date = DateTime.Now, buf = pingResponse.Buffer.Length, TTL = pingResponse.Options.Ttl }); dataGrid1.Items.Refresh(); dataGrid1.Items.MoveCurrentToLast(); dataGrid1.ScrollIntoView(dataGrid1.SelectedItem); sw = aFile.AppendText(); sw.WriteLine(getUSK.id + "|" + getUSK.abonent + "|" + getUSK.address + "|" + getUSK.ip + "|" + pingResponse.RoundtripTime + "|" + pingResponse.Status + "|" + DateTime.Now + "|" + pingResponse.Buffer.Length + "|" + pingResponse.Options.Ttl); sw.Close(); } } public void GetUSK() //формируем список уск с помощью запросов к БД { String comm = ""; connectStr = @"User=***;Password=***;Database=D:\Program Files (x86)\ASDK\DB\firenet.GDB;DataSource=***; Port=***;Dialect=3; Charset=NONE;Role=;Connection lifetime=15;Pooling=true; MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0;"; connection.ConnectionString = connectStr; command.Connection = connection; comm = "SELECT U.USK_ID, A.AB_NAME, U.USK_ADR_ID, U.USK_IP FROM USK U, ABONENT A WHERE U.USK_AB_ID=AB_ID AND (U.USK_TYPE=2 OR U.USK_TYPE=1 OR U.USK_TYPE=3)"; command.CommandText = comm; connection.Open(); FbDataReader r = command.ExecuteReader(); while (r.Read()) { USK curUSK = new USK(); curUSK.id = r.GetString(0); curUSK.abonent = r.GetString(1); curUSK.address_id = r.GetString(2); curUSK.ip = r.GetString(3); list_of_USK.Add(curUSK); } connection.Close(); foreach (var item in list_of_USK) { comm = "SELECT ADR_STR FROM WP_GET_ADRESS(" + item.address_id + ",3)"; command.CommandText = comm; connection.Open(); FbDataReader rr = command.ExecuteReader(); while (rr.Read()) { item.address = rr.GetString(0); } connection.Close(); } } private void button1_Click(object sender, RoutedEventArgs e) { JustPing(); // вызов пинга для одного уск } } //контейнер для УСК (первоначальная инфа из базы) public class USK { public String id; public String abonent; public String ip; public String address_id; public String address; } // контейнер результатов ping'а public class resPing { public Int32 id {get; set;} public String abonent{get; set;} public String ip { get; set; } public String address { get; set; } public String status { get; set; } public Int32 time { get; set; } public DateTime date { get; set; } public Int32 buf { get; set; } public Int32 TTL { get; set; } } //конвертер статуса в кисть class StatusToColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return (String)value != "Success" ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.White); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new Exception("The method or operation is not implemented."); } } }
Решение задачи: «Получение ip устройства при неудачном запросе Ping.SendAsync»
textual
Листинг программы
public void SendAsync(IPAddress address, int timeout, byte[] buffer, PingOptions options, Object userToken)
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д