Form_Main.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Threading;
  10. using System.Net;
  11. using System.Net.Sockets;
  12. using System.Text.RegularExpressions;
  13. namespace NetworkDiscovery
  14. {
  15. public partial class Form_Main : Form
  16. {
  17. #region Constants
  18. private const int _UDP_TX_PORT = 49049; // порт передачи сообщений
  19. private const int _UDP_RX_PORT = 49049; // порт приема сообщений
  20. private const int _delay = 500; // интервал между отсылками сообщений
  21. private const int _timeOut = 5000; //время тайм-аута по приёму сообщений
  22. private const int _timeOutAfterApply = 10000; //время тайм-аута по приему сообщений после
  23. //изменения IP
  24. #endregion
  25. #region Fields
  26. private List<string> _messages = new List<string>();
  27. protected UdpClient _listener;
  28. private List<string> _sendMessages = new List<string>() { "partno;serno;MAC;sw version;;;stm32id;;prodate;status;;" };
  29. private bool _isAfterApply = false;
  30. #endregion
  31. public Form_Main()
  32. {
  33. InitializeComponent();
  34. }
  35. private void Button_Start_Click(object sender, EventArgs e)
  36. {
  37. Thread t = new Thread(UpdateDeviceList);
  38. t.Start();
  39. }
  40. private void Button_About_Click(object sender, EventArgs e)
  41. {
  42. Form_About inf_form = new Form_About();
  43. inf_form.ShowDialog();
  44. }
  45. /// <summary>
  46. /// Обновление списка устройств.
  47. /// </summary>
  48. private void UpdateDeviceList()
  49. {
  50. Invoke((Action)(() => Button_Start.Enabled = false));
  51. Invoke((Action)(() => label.Visible = false));
  52. Invoke((Action)(() => progressBar.Style = ProgressBarStyle.Marquee));
  53. dataGridView.Rows.Clear();
  54. StartListener();
  55. UpdateDataGridView();
  56. Invoke((Action)(() => Button_Start.Enabled = true));
  57. Invoke((Action)(() => progressBar.Style = ProgressBarStyle.Blocks));
  58. try
  59. {
  60. Invoke((Action)(() => label.Text = "Найдено " + (dataGridView.RowCount)));
  61. }
  62. catch { }
  63. Invoke((Action)(() => label.Visible = true));
  64. }
  65. /// <summary>
  66. /// Обновление таблицы
  67. /// </summary>
  68. private void UpdateDataGridView()
  69. {
  70. for (int i = 0; i < _messages.Count; i++)
  71. {
  72. String[] substring = Regex.Split(_messages[i], ";");
  73. if (substring.Length == 12)
  74. {
  75. string[] row = { substring[1], substring[11], substring[2], substring[0], substring[3] };
  76. dataGridView.Rows.Add(row);
  77. }
  78. }
  79. _messages.Clear();
  80. }
  81. /// <summary>
  82. /// Запуск слушателя upd-запросов
  83. /// </summary>
  84. protected void StartListener()
  85. {
  86. Thread sender = new Thread(Sender);
  87. sender.Start();
  88. try
  89. {
  90. if (CheckPortFree(_UDP_RX_PORT))
  91. _listener = new UdpClient(_UDP_RX_PORT);
  92. else return;
  93. IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, _UDP_RX_PORT);
  94. List<IPAddress> myIpList = GetMyIpList();
  95. DateTime startTime = DateTime.Now;
  96. while (true)
  97. {
  98. if (_listener.Available > 0)
  99. {
  100. byte[] bytes = _listener.Receive(ref groupEP);
  101. if ((!_messages.Contains(Encoding.UTF8.GetString(bytes, 0, bytes.Length) + groupEP.Address.ToString())) && (!myIpList.Contains(groupEP.Address)))
  102. _messages.Add(Encoding.UTF8.GetString(bytes, 0, bytes.Length) + groupEP.Address.ToString());
  103. }
  104. int timeOut = _isAfterApply ? _timeOutAfterApply : _timeOut;
  105. if (DateTime.Now.Subtract(startTime) >= new TimeSpan(0, 0, 0, 0, timeOut))
  106. break;
  107. }
  108. }
  109. catch (Exception ex)
  110. {
  111. MessageBox.Show("Неудачная попытка использования порта: закройте другие экземляры программы и попробуйте заново", "Порт Занят",
  112. MessageBoxButtons.OK, MessageBoxIcon.Error);
  113. }
  114. finally
  115. {
  116. sender.Abort();
  117. _listener.Close();
  118. }
  119. }
  120. /// <summary>
  121. /// Проверка доступности порта
  122. /// </summary>
  123. /// <param name="nPortNum">Номер порта</param>
  124. /// <returns>Истина, если порт доступен</returns>
  125. public static bool CheckPortFree(int nPortNum)
  126. {
  127. bool bCheckResult = true;
  128. Socket s = null;
  129. try
  130. {
  131. s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  132. s.Bind(new IPEndPoint(IPAddress.Loopback, nPortNum));
  133. }
  134. catch (Exception e)
  135. {
  136. MessageBox.Show("Порт занят сторонним приложением", "Порт Занят",
  137. MessageBoxButtons.OK, MessageBoxIcon.Error);
  138. bCheckResult = false;
  139. }
  140. finally
  141. {
  142. s.Close();
  143. }
  144. return bCheckResult;
  145. }
  146. protected static List<IPAddress> GetMyIpList()
  147. {
  148. List<IPAddress> MyIpList = new List<IPAddress>();
  149. String strHostName = Dns.GetHostName();
  150. IPHostEntry iphostentry = Dns.GetHostEntry(strHostName);
  151. foreach (IPAddress ipaddress in iphostentry.AddressList)
  152. {
  153. MyIpList.Add(ipaddress);
  154. }
  155. return MyIpList;
  156. }
  157. private void Sender()
  158. {
  159. try
  160. {
  161. while (true)
  162. {
  163. _messages.ForEach(m => SendBroadcast(m));
  164. Thread.Sleep(_delay);
  165. }
  166. }
  167. catch (ThreadAbortException e)
  168. {
  169. Thread.ResetAbort();
  170. return;
  171. }
  172. }
  173. protected void SendBroadcast(String message)
  174. {
  175. UdpClient client = new UdpClient();
  176. IPEndPoint ip = new IPEndPoint(IPAddress.Broadcast, _UDP_TX_PORT);
  177. Byte[] bytes = Encoding.ASCII.GetBytes(message);
  178. try
  179. {
  180. client.Send(bytes, bytes.Length, ip);
  181. }
  182. catch (Exception e)
  183. {
  184. MessageBox.Show("Порт занят, попробуйте еще раз", "Порт отправки занят",
  185. MessageBoxButtons.OK, MessageBoxIcon.Error);
  186. }
  187. finally
  188. {
  189. client.Close();
  190. }
  191. }
  192. private void dataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
  193. {
  194. string ip = dataGridView.Rows[dataGridView.CurrentCell.RowIndex].Cells[1].Value.ToString();
  195. string serno = dataGridView.Rows[dataGridView.CurrentCell.RowIndex].Cells[0].Value.ToString();
  196. Form_IpConfig form = new Form_IpConfig(ip, serno);
  197. form.ShowDialog();
  198. _isAfterApply = form.isChanged;
  199. if (!_isAfterApply) return;
  200. Thread t = new Thread(UpdateDeviceList);
  201. t.Start();
  202. }
  203. }
  204. }