Получение 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)

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 3.9 из 5
Похожие ответы