Получение ip устройства при неудачном запросе Ping.SendAsync - C#

Узнай цену своей работы

Формулировка задачи:

Всем привет! Надеюсь, вы поможете найти решение моей проблемы... Цели создаваемой программы: 1) ping одного устройства по запросу пользователя; 2) ping группы устройств по таймеру. Суть проблемы: если использовать обычный Ping.Send программа виснет намертво при множественных запросах пинга и наличии недоступных устройств. Поэтому решила использовать асинхронный пинг

Ping.SendAsync

. Теперь проблема в том, что

PingReply

, возвращаемый при неудачном пинге содержит нулевые параметры и, соответственно, адрес 0.0.0.0. Как мне в обработчике

pingSender_Complete

получить адрес, который программа пыталась пинговать? Сейчас в коде я использую глобальную переменнную

currentUSK

, но в случае группового пинга, когда все результаты появляются с разной задержкой, они, естественно, получают самое последнее значение этой переменной. Можно ли адрес или весь объект

USK

передать в обработчик события? Информации на доступном для меня уровне в интернете не нашла. Подскажите, куда копать?
Листинг программы
  1. namespace PingUSK
  2. {
  3. /// <summary>
  4. /// Логика взаимодействия для MainWindow.xaml
  5. /// </summary>
  6. public partial class MainWindow : Window
  7. {
  8. //глобальные переменные
  9. public static String connectStr;
  10. FbConnection connection = new FbConnection(connectStr);
  11. FbCommand command = new FbCommand();
  12. FbDataAdapter dataAdapter = new FbDataAdapter();
  13. DataTable dt = new DataTable();
  14. List<USK> list_of_USK = new List<USK>();
  15. //поток записи и чтения
  16. StreamWriter sw;
  17. StreamReader sr;
  18. //файл
  19. FileInfo aFile;
  20. USK currentUSK = new USK();
  21. ObservableCollection<resPing> log = new ObservableCollection<resPing>();
  22. System.Threading.Timer tm;
  23. AutoResetEvent resetEvent = new AutoResetEvent(false);
  24. public MainWindow()
  25. {
  26. InitializeComponent();
  27. // получаю список УСК
  28. GetUSK();
  29. //заполняю комбобокс значениями из списка УСК
  30. foreach (var item in list_of_USK)
  31. {
  32. comboBox1.Items.Add(item.abonent + " | " + item.ip + " | " + item.address);
  33. }
  34. comboBox1.SelectedIndex = 0;
  35. //создание текстового файла с базой или его открытие
  36. aFile = new FileInfo("d:\\PingUSK.txt");
  37. if (aFile.Exists == false) { aFile.Create(); }
  38. //чтение из файла, вывод в листбокс
  39. sr = aFile.OpenText();
  40. while (!sr.EndOfStream)
  41. {
  42. try
  43. {
  44. String str = sr.ReadLine();
  45. String[] mas = str.Split('|');
  46. 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]) });
  47. }
  48. catch { }
  49. }
  50. sr.Close();
  51. dataGrid1.ItemsSource = log;
  52. dataGrid1.Items.Refresh();
  53. try
  54. {
  55. dataGrid1.Items.MoveCurrentToLast();
  56. dataGrid1.ScrollIntoView(dataGrid1.SelectedItem);
  57. }
  58. catch { }
  59. //запуск таймера
  60. tm = new System.Threading.Timer(Callback, null, new TimeSpan(0, 1, 0), new TimeSpan(0, 1, 0));
  61. }
  62. // процедура, выполняемая при срабатывании таймера (коллективный пинг)
  63. private void Callback(object param)
  64. {
  65. foreach (var item in list_of_USK)
  66. {
  67. try
  68. {
  69. Dispatcher.BeginInvoke(DispatcherPriority.Send, (Action<USK>)PingForCircle, item);
  70. }
  71. catch { }
  72. }
  73. }
  74. // пинг одного устройства (на выбор пользователя)
  75. public void JustPing()
  76. {
  77. Int32 i = comboBox1.SelectedIndex;
  78. USK cur = list_of_USK[i];
  79. currentUSK = cur;
  80. SendPing(cur);
  81. }
  82. // массовый пинг
  83. public void PingForCircle(USK usk)
  84. {
  85. currentUSK = usk;
  86. SendPing(usk);
  87. }
  88. private void SendPing(USK _cur)
  89. {
  90. USK cur = _cur;
  91. Ping pingSender = new System.Net.NetworkInformation.Ping();
  92. // событие при завершении пинга
  93. pingSender.PingCompleted += new PingCompletedEventHandler(pingSender_Complete);
  94. // установки
  95. byte[] packetData = Encoding.ASCII.GetBytes("................................");
  96. PingOptions packetOptions = new PingOptions(50, true);
  97. pingSender.SendAsync(cur.ip, 2000, packetData, packetOptions, resetEvent); //посылка асинхронного пинга
  98. }
  99. private void pingSender_Complete(object sender, PingCompletedEventArgs e)
  100. {
  101. if (e.Cancelled)
  102. {
  103. ((AutoResetEvent)e.UserState).Set();
  104. }
  105. else if (e.Error != null)
  106. {
  107. MessageBox.Show("An error occured: " + e.Error + "\r\n");
  108. ((AutoResetEvent)e.UserState).Set();
  109. }
  110. else
  111. {
  112. PingReply pingResponse = e.Reply;
  113. // вызов процедуры вывода результатов
  114. ShowPingResults(pingResponse);
  115. }
  116. }
  117. public void ShowPingResults(PingReply pingResponse)
  118. {
  119. String adr = pingResponse.Address.ToString();
  120. USK getUSK = new USK();
  121. // поиск уск в списке по ip
  122. foreach (var item in list_of_USK)
  123. {
  124. if (item.ip == adr) { getUSK = item; break; }
  125. }
  126. //если пинг неудачный...
  127. if (pingResponse.RoundtripTime == 0)
  128. {
  129. 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 });
  130. dataGrid1.Items.Refresh();
  131. dataGrid1.Items.MoveCurrentToLast();
  132. dataGrid1.ScrollIntoView(dataGrid1.SelectedItem);
  133. sw = aFile.AppendText();
  134. sw.WriteLine(getUSK.id + "|" + getUSK.abonent + "|" + getUSK.address + "|" + getUSK.ip + "|" + pingResponse.RoundtripTime + "|" + pingResponse.Status + "|" + DateTime.Now + "|" + pingResponse.Buffer.Length + "|" + "0");
  135. sw.Close();
  136. }
  137. // если пинг прошел...
  138. else
  139. {
  140. 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 });
  141. dataGrid1.Items.Refresh();
  142. dataGrid1.Items.MoveCurrentToLast();
  143. dataGrid1.ScrollIntoView(dataGrid1.SelectedItem);
  144. sw = aFile.AppendText();
  145. sw.WriteLine(getUSK.id + "|" + getUSK.abonent + "|" + getUSK.address + "|" + getUSK.ip + "|" + pingResponse.RoundtripTime + "|" + pingResponse.Status + "|" + DateTime.Now + "|" + pingResponse.Buffer.Length + "|" + pingResponse.Options.Ttl);
  146. sw.Close();
  147. }
  148. }
  149. public void GetUSK() //формируем список уск с помощью запросов к БД
  150. {
  151. String comm = "";
  152. 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;";
  153. connection.ConnectionString = connectStr;
  154. command.Connection = connection;
  155. 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)";
  156. command.CommandText = comm;
  157. connection.Open();
  158. FbDataReader r = command.ExecuteReader();
  159. while (r.Read())
  160. {
  161. USK curUSK = new USK();
  162. curUSK.id = r.GetString(0);
  163. curUSK.abonent = r.GetString(1);
  164. curUSK.address_id = r.GetString(2);
  165. curUSK.ip = r.GetString(3);
  166. list_of_USK.Add(curUSK);
  167. }
  168. connection.Close();
  169. foreach (var item in list_of_USK)
  170. {
  171. comm = "SELECT ADR_STR FROM WP_GET_ADRESS(" + item.address_id + ",3)";
  172. command.CommandText = comm;
  173. connection.Open();
  174. FbDataReader rr = command.ExecuteReader();
  175. while (rr.Read())
  176. {
  177. item.address = rr.GetString(0);
  178. }
  179. connection.Close();
  180. }
  181. }
  182. private void button1_Click(object sender, RoutedEventArgs e)
  183. {
  184. JustPing(); // вызов пинга для одного уск
  185. }
  186. }
  187. //контейнер для УСК (первоначальная инфа из базы)
  188. public class USK
  189. {
  190. public String id;
  191. public String abonent;
  192. public String ip;
  193. public String address_id;
  194. public String address;
  195. }
  196. // контейнер результатов ping'а
  197. public class resPing
  198. {
  199. public Int32 id {get; set;}
  200. public String abonent{get; set;}
  201. public String ip { get; set; }
  202. public String address { get; set; }
  203. public String status { get; set; }
  204. public Int32 time { get; set; }
  205. public DateTime date { get; set; }
  206. public Int32 buf { get; set; }
  207. public Int32 TTL { get; set; }
  208. }
  209. //конвертер статуса в кисть
  210. class StatusToColorConverter : IValueConverter
  211. {
  212. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  213. {
  214. return (String)value != "Success" ?
  215. new SolidColorBrush(Colors.Red)
  216. : new SolidColorBrush(Colors.White);
  217. }
  218. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  219. {
  220. throw new Exception("The method or operation is not implemented.");
  221. }
  222. }
  223. }

Решение задачи: «Получение ip устройства при неудачном запросе Ping.SendAsync»

textual
Листинг программы
  1. public void SendAsync(IPAddress address, int timeout, byte[] buffer, PingOptions options, Object userToken)

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


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

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

10   голосов , оценка 3.9 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы