//отправка сообщения
        public int SendMessage(string Message, string IP, int PORT)
        {
            //количество отправленных байт
            int cendCount = 0;

            try
            {
                //создаем клиента
                DiffieClient diffieClient = new DiffieClient();
                //получаем порт текщего клиента
                this.Dispatcher.Invoke(() => {
                    diffieClient = new DiffieClient(text_ThisIP.Text);
                });
                //создаем клиент отправки
                UdpClient client = new UdpClient(IP, PORT);
                //генерируем сообщение и с дописаным портом отправлителя
                byte[] data = Encoding.UTF8.GetBytes(Message + "_" + diffieClient.PORT);
                //отправляем сообщение
                cendCount = client.Send(data, data.Length);
                //закрываем клиент отправки
                client.Close();
            }
            catch (Exception ex)
            {
                //воводим ошибку
                Debug(ex.Message);
            }
            //возвращаем количество отправленных байт
            return(cendCount);
        }
 //проверка связи
 private void Btn_CreateConnect_Click(object sender, RoutedEventArgs e)
 {
     try
     {
         //задаем массив клиентов
         ClientsList = new List <DiffieClient>();
         //записываем первого клиента самого себя
         ClientsList.Add(new DiffieClient(text_ThisIP.Text));
         //получаем всех остальных клиентов и разделяем их
         var IPlist = text_IPlist.Text.Split('\n');
         //перебераем всех клиентов
         foreach (var item in IPlist)
         {
             //создаем нового клиента
             DiffieClient client = new DiffieClient(item);
             //добавляем клиента в массив
             ClientsList.Add(client);
             //отправляем запрос на проверку связи
             SendMessage("testConnect:", client.IP, client.PORT);
         }
         //сортируем клиентов по порту
         ClientsList.Sort();
     }
     catch (Exception ex)
     {
         //если происходит ошибка выводим ее
         Debug(ex.Message);
     }
 }
        //Реализация интерфейса
        public int CompareTo(object obj)
        {
            //пробуем получить клиента
            DiffieClient client = obj as DiffieClient;

            if (client != null)
            {
                //возвращаем результат сравления
                return(this.PORT.CompareTo(client.PORT));
            }
            else
            {
                //выбразываем ошибку
                throw new Exception("Невозможно сравнить два объекта");
            }
        }
 public MainWindow()
 {
     InitializeComponent();
     // событие проверки связи
     btn_CreateConnect.Click += Btn_CreateConnect_Click;
     // событие запуска сервера
     btn_StartListen.Click += (sender, e) => {
         Debug("Прослушивание запущено");
         //иницилизация запуска сервера
         ListenAnswer = new Thread(new ThreadStart(() => {
             string ThisIp = "";
             //получение ip клиента с формы
             this.Dispatcher.Invoke(() => {
                 ThisIp = text_ThisIP.Text;
             });
             //получние ip и порта из строки
             DiffieClient diffieClient = new DiffieClient(ThisIp);
             // инициальзация клиента
             UdpClient client = new UdpClient(diffieClient.PORT);
             // инициальзауия параметров прослушки
             IPEndPoint ip = new IPEndPoint(IPAddress.Any, diffieClient.PORT);
             // бесконечный цикл прослушки
             while (true)
             {
                 // завершение цикла
                 if (ListenAnswerBreak)
                 {
                     break;
                 }
                 try
                 {
                     //инициализация остановки прослушки и освобождение ресурсов
                     StopListen = () =>
                     {
                         client.Close();
                         client.Dispose();
                     };
                     //получение данных из сети
                     byte[] data = client.Receive(ref ip);
                     //конвертирование байтов в строку
                     string message = Encoding.UTF8.GetString(data);
                     //отправка команды в диспетчер команд
                     CommandDispetcher(message, ip);
                 }
                 // если ошибка
                 catch (Exception ex)
                 {
                     // пишем ошибку
                     this.Dispatcher.Invoke(() => {
                         Debug("Ошибка " + ex.Message);
                     });
                 }
             }
             //завершение работы клиента
             client.Close();
         }));
         //запуск сервера прослушки
         ListenAnswer.Start();
     };
     btn_CreateKey.Click += (sender, e) => {
         //начало генерации ключа
         //перебор всех участников и отправка всем команды генерации приватного ключа
         foreach (var item in ClientsList)
         {
             SendMessage("createKey:", item.IP, item.PORT);
         }
         //ожидаем чтобы все успели сгенерировать ключ
         Thread.Sleep(500);
         //начало генерации ключа команда:публичный ключ:какому клиенту адресуется:сколько итераций осталось
         SendMessage("getPublicKey:" + PublicKey + ":0" + ":" + (ClientsList.Count), ClientsList[0].IP, ClientsList[0].PORT);
     };
 }
        //диспетчер команд
        public void CommandDispetcher(string command, IPEndPoint sender)
        {
            //получение порта клиента
            string[] port = command.Split('_');
            //получение данных и команды
            string[] data = port[0].Split(':');
            switch (data[0])
            {
            //отправка запроса на проверку связи
            case "testConnect":
                //отправка всем что соеденение есть
                this.Dispatcher.Invoke(() => {
                    SendMessage("testConnectResult:", sender.Address.ToString(), int.Parse(port[1]));
                    //Debug(string.Format("Получено " + command + " от ", sender.Address.ToString(), sender.Port));
                });
                break;

            //команда завершения проверки соединения
            case "testConnectResult":
                this.Dispatcher.Invoke(() => {
                    Debug(string.Format("Связь с {0}:{1} установлена", sender.Address.ToString(), port[1]));
                });
                break;

            //команда генерации ключа
            case "createKey":
                //получаем порт клиента
                int thisPort = 0;
                this.Dispatcher.Invoke(() => { thisPort = new DiffieClient(text_ThisIP.Text).PORT; });
                //так как рандом зависит от времени компьютера, а все генерируют ключ в раз, то мы прибавляем к времени компьютера порт клиента
                Random random = new Random(DateTime.UtcNow.Millisecond + thisPort);
                //геренрируем случайное число
                SecretKey = random.Next(2, 16);
                this.Dispatcher.Invoke(() => {
                    Debug(string.Format("Сгенерирован секретный ключ " + SecretKey, sender.Address.ToString(), port[1]));
                });
                break;

            //получение публичного ключа и генерация настроящего ключа
            case "getPublicKey":
                //получение публичного ключа предыдущего клиента
                int publicKeyPrev = int.Parse(data[1]);
                //получение ID предыдущего клиента
                int senderId = int.Parse(data[2]);
                //получение оставшегося количества итераций
                int count = int.Parse(data[3]) - 1;
                //вывод полученных данных
                this.Dispatcher.Invoke(() => {
                    Debug("publicKeyPrev " + publicKeyPrev + " senderId " + senderId);
                });
                //генерация публичного ключа если это первая итерация иначе прололжаем генерацию
                if (publicKeyPrev == 0)
                {
                    PublicKey = Convert.ToInt32(Math.Pow(g, SecretKey) % p);
                }
                else
                {
                    PublicKey = Convert.ToInt32(Math.Pow(publicKeyPrev, SecretKey) % p);
                }
                //если количество итераций закончилось
                if (count == 0)
                {
                    //опять задаем количество итераций
                    count = ClientsList.Count - 1;
                    //если настоящий ключ уже был сгенерирован
                    //то значит все сгенерировали его и начался второй круг
                    if (TrueKey != 0)
                    {
                        //отправляем чтобы все показали настоящий ключ
                        foreach (var item in ClientsList)
                        {
                            SendMessage("ShowKey:", item.IP, item.PORT);
                        }
                        //и завершаем генерацию ключа
                        break;
                    }
                    else
                    {
                        //иначе генерируем настоящий ключ
                        TrueKey = PublicKey;
                        //выводим его на экран
                        this.Dispatcher.Invoke(() => {
                            Debug("TrueKey " + TrueKey);
                        });
                        // и заново генерируем публичный ключ
                        PublicKey = Convert.ToInt32(Math.Pow(g, SecretKey) % p);
                    }
                }
                // если id отправляемого дошел до конца, то начинаем сначала
                if (senderId == ClientsList.Count - 1)
                {
                    senderId = -1;
                }
                //потправляем публичный ключ следующему клиенту
                SendMessage("getPublicKey:" + PublicKey + ":" + (senderId + 1) + ":" + count, ClientsList[senderId + 1].IP, ClientsList[senderId + 1].PORT);
                break;

            //показываем настоящий ключ
            case "ShowKey":
                this.Dispatcher.Invoke(() => {
                    Debug("Общий ключ " + TrueKey);
                });
                break;

            default:
                break;
            }
        }