123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using System.Threading;
- using System.Net;
- using System.Net.Sockets;
- using System.Text.RegularExpressions;
- namespace NetworkDiscovery
- {
- public partial class Form_Main : Form
- {
- #region Constants
- private const int _UDP_TX_PORT = 49049; // порт передачи сообщений
- private const int _UDP_RX_PORT = 49049; // порт приема сообщений
- private const int _delay = 500; // интервал между отсылками сообщений
- private const int _timeOut = 5000; //время тайм-аута по приёму сообщений
- private const int _timeOutAfterApply = 10000; //время тайм-аута по приему сообщений после
- //изменения IP
- #endregion
- #region Fields
- private List<string> _messages = new List<string>();
- protected UdpClient _listener;
- private List<string> _sendMessages = new List<string>() { "partno;serno;MAC;sw version;;;stm32id;;prodate;status;;" };
- private bool _isAfterApply = false;
- #endregion
- public Form_Main()
- {
- InitializeComponent();
- }
- private void Button_Start_Click(object sender, EventArgs e)
- {
- Thread t = new Thread(UpdateDeviceList);
- t.Start();
- }
- private void Button_About_Click(object sender, EventArgs e)
- {
- Form_About inf_form = new Form_About();
- inf_form.ShowDialog();
- }
- /// <summary>
- /// Обновление списка устройств.
- /// </summary>
- private void UpdateDeviceList()
- {
- Invoke((Action)(() => Button_Start.Enabled = false));
- Invoke((Action)(() => label.Visible = false));
- Invoke((Action)(() => progressBar.Style = ProgressBarStyle.Marquee));
- dataGridView.Rows.Clear();
- StartListener();
- UpdateDataGridView();
- Invoke((Action)(() => Button_Start.Enabled = true));
- Invoke((Action)(() => progressBar.Style = ProgressBarStyle.Blocks));
- try
- {
- Invoke((Action)(() => label.Text = "Найдено " + (dataGridView.RowCount)));
- }
- catch { }
- Invoke((Action)(() => label.Visible = true));
- }
- /// <summary>
- /// Обновление таблицы
- /// </summary>
- private void UpdateDataGridView()
- {
- for (int i = 0; i < _messages.Count; i++)
- {
- String[] substring = Regex.Split(_messages[i], ";");
- if (substring.Length == 12)
- {
- string[] row = { substring[1], substring[11], substring[2], substring[0], substring[3] };
- dataGridView.Rows.Add(row);
- }
- }
- _messages.Clear();
- }
- /// <summary>
- /// Запуск слушателя upd-запросов
- /// </summary>
- protected void StartListener()
- {
- Thread sender = new Thread(Sender);
- sender.Start();
- try
- {
- if (CheckPortFree(_UDP_RX_PORT))
- _listener = new UdpClient(_UDP_RX_PORT);
- else return;
- IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, _UDP_RX_PORT);
- List<IPAddress> myIpList = GetMyIpList();
- DateTime startTime = DateTime.Now;
- while (true)
- {
- if (_listener.Available > 0)
- {
- byte[] bytes = _listener.Receive(ref groupEP);
- if ((!_messages.Contains(Encoding.UTF8.GetString(bytes, 0, bytes.Length) + groupEP.Address.ToString())) && (!myIpList.Contains(groupEP.Address)))
- _messages.Add(Encoding.UTF8.GetString(bytes, 0, bytes.Length) + groupEP.Address.ToString());
- }
- int timeOut = _isAfterApply ? _timeOutAfterApply : _timeOut;
- if (DateTime.Now.Subtract(startTime) >= new TimeSpan(0, 0, 0, 0, timeOut))
- break;
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show("Неудачная попытка использования порта: закройте другие экземляры программы и попробуйте заново", "Порт Занят",
- MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- sender.Abort();
- _listener.Close();
- }
- }
- /// <summary>
- /// Проверка доступности порта
- /// </summary>
- /// <param name="nPortNum">Номер порта</param>
- /// <returns>Истина, если порт доступен</returns>
- public static bool CheckPortFree(int nPortNum)
- {
- bool bCheckResult = true;
- Socket s = null;
- try
- {
- s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- s.Bind(new IPEndPoint(IPAddress.Loopback, nPortNum));
- }
- catch (Exception e)
- {
- MessageBox.Show("Порт занят сторонним приложением", "Порт Занят",
- MessageBoxButtons.OK, MessageBoxIcon.Error);
- bCheckResult = false;
- }
- finally
- {
- s.Close();
- }
- return bCheckResult;
- }
- protected static List<IPAddress> GetMyIpList()
- {
- List<IPAddress> MyIpList = new List<IPAddress>();
- String strHostName = Dns.GetHostName();
- IPHostEntry iphostentry = Dns.GetHostEntry(strHostName);
- foreach (IPAddress ipaddress in iphostentry.AddressList)
- {
- MyIpList.Add(ipaddress);
- }
- return MyIpList;
- }
- private void Sender()
- {
- try
- {
- while (true)
- {
- _messages.ForEach(m => SendBroadcast(m));
- Thread.Sleep(_delay);
- }
- }
- catch (ThreadAbortException e)
- {
- Thread.ResetAbort();
- return;
- }
- }
- protected void SendBroadcast(String message)
- {
- UdpClient client = new UdpClient();
- IPEndPoint ip = new IPEndPoint(IPAddress.Broadcast, _UDP_TX_PORT);
- Byte[] bytes = Encoding.ASCII.GetBytes(message);
- try
- {
- client.Send(bytes, bytes.Length, ip);
- }
- catch (Exception e)
- {
- MessageBox.Show("Порт занят, попробуйте еще раз", "Порт отправки занят",
- MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- client.Close();
- }
- }
- private void dataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
- {
- string ip = dataGridView.Rows[dataGridView.CurrentCell.RowIndex].Cells[1].Value.ToString();
- string serno = dataGridView.Rows[dataGridView.CurrentCell.RowIndex].Cells[0].Value.ToString();
- Form_IpConfig form = new Form_IpConfig(ip, serno);
- form.ShowDialog();
- _isAfterApply = form.isChanged;
- if (!_isAfterApply) return;
- Thread t = new Thread(UpdateDeviceList);
- t.Start();
- }
- }
- }
|