/// <summary> /// Конструктор класса. Ему нужно передавать принятого клиента от TcpListener /// </summary> /// <param name="Client"></param> public Client(TcpClient Client) { try { bool disconnect = false; while ((!Loger.closeAllThreads) & (!disconnect)) { // Объявим строку, в которой будет хранится запрос клиента string Request = ""; // Буфер для хранения принятых от клиента данных byte[] Buffer = new byte[8]; // Переменная для хранения количества байт, принятых от клиента int Count; while ((Count = Client.GetStream().Read(Buffer, 0, Buffer.Length)) > 0) { //stop_send = true; Request += Encoding.UTF8.GetString(Buffer, 0, Count); // Пакет пришел полностью if (Request.IndexOf("<end>") >= 0) { break; } // Превышен разумный размер пакета if (Request.Length > 4096) { break; } } Request = Request.Replace("<end>", ""); if (Request == "") return; DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Packet)); Packet packet = (Packet)ser.ReadObject(new System.IO.MemoryStream(Encoding.UTF8.GetBytes(Request))); if (packet.cmd != null) { ClientInfo clientinfo; switch (packet.cmd) { case "connection": // Добавляем в список клиентов TcpServer.ListOfClients.Add(new ClientInfo(ref Client)); // Получаем ссылку на экземпляр клиента clientinfo = TcpServer.ListOfClients.Find(ci => ci.Client.Equals(Client)); // Сохраняем имя подключенного клиента // Определяем каккая версия клиента подключена if (packet.nameClient == null) { // В старой версии протокола предпологалось, что клиентам // присваевается идентификатор при регистрации byte[] number = Encoding.UTF8.GetBytes("385"); Client.GetStream().Write(number, 0, number.Length); clientinfo.Name = "Старая версия клиента 'Хариус'"; } else { // В новой версии протокола можно передавать версию сервера // при подключении. А можно и не передавать :) byte[] number = Encoding.UTF8.GetBytes(Application.ProductVersion.ToString()); Client.GetStream().Write(number, 0, number.Length); clientinfo.Name = packet.nameClient.ToString(); } // Сохраняем IP-адресс подключенного клиента clientinfo.IpAdress = ((IPEndPoint)Client.Client.RemoteEndPoint).Address.ToString(); // Запись в лог-файл Loger.WriteToFile("Подключен новый клиент '" + clientinfo.Name + "' (ip: " + clientinfo.IpAdress + ") ..."); break; case "disconnect": disconnect = true; // Запись в лог-файл Loger.WriteToFile("Отключился клиент " + Convert.ToString(packet.nameClient) + " " + Convert.ToString(((IPEndPoint)Client.Client.LocalEndPoint).Address) + " ..."); break; case "refresh": NevodCommand refreshCmd = new NevodCommand("refresh", packet.numberKP, packet.parametr); // Получаем ссылку на экземпляр клиента clientinfo = TcpServer.ListOfClients.Find(ci => ci.Client.Equals(Client)); Loger.SendMsg((int)MessagerId.Log, (int)MessagerId.TcpServer, "Клиент '" + clientinfo.Name + "' (ip: " + clientinfo.IpAdress + ") принудительно запросил обновить данные для КП-" + Convert.ToString(packet.numberKP)); DataServer.hendCommmands.Add(refreshCmd); DataServer.WaitHandler.Set(); break; case "switch": // Получаем ссылку на экземпляр клиента clientinfo = TcpServer.ListOfClients.Find(ci => ci.Client.Equals(Client)); // Проверяем есть ли у пользователя права на телеуправление if (TcpServer.ListOfUsers.FindIndex( name => name == Convert.ToString(packet.nameClient)) == -1) { // Запись в лог-файл Loger.WriteToFile("Клиент '" + clientinfo.Name + "' (ip: " + clientinfo.IpAdress + ") заблокирована операция кратковременной подачи напряжения. КП №" + Convert.ToString(packet.numberKP) + " выход №" + Convert.ToString(packet.parametr) + "Причина: нет прав на телеуправление."); break; } // Добавить операцию телеуправления в список команд NevodCommand tempCmd = new NevodCommand("switch", packet.numberKP, packet.parametr); DataServer.hendCommmands.Add(tempCmd); DataServer.WaitHandler.Set(); // Запись в лог-файл Loger.WriteToFile("Клиент '" + clientinfo.Name + "' (ip: " + clientinfo.IpAdress + ") запустил операцию кратковременной подачи напряжения. КП №" + Convert.ToString(packet.numberKP) + " выход №" + Convert.ToString(packet.parametr)); break; case "on": // Получаем ссылку на экземпляр клиента clientinfo = TcpServer.ListOfClients.Find(ci => ci.Client.Equals(Client)); // Проверяем есть ли у пользователя права на телеуправление if (TcpServer.ListOfUsers.FindIndex( name => name == Convert.ToString(packet.nameClient)) == -1) { // Запись в лог-файл Loger.WriteToFile("Клиент '" + clientinfo.Name + "' (ip: " + clientinfo.IpAdress + ") заблокирована операция ТУ. Подать напряжение на КП №" + Convert.ToString(packet.numberKP) + " выход №" + Convert.ToString(packet.parametr) + "Причина: нет прав на телеуправление."); break; } // Добавить операцию телеуправления в список команд NevodCommand onCmd = new NevodCommand("on", packet.numberKP, packet.parametr); DataServer.hendCommmands.Add(onCmd); DataServer.WaitHandler.Set(); // Запись в лог-файл Loger.WriteToFile("Клиент '" + clientinfo.Name + "' (ip: " + clientinfo.IpAdress + ") запустил операцию ТУ. Подать напряжение на КП №" + Convert.ToString(packet.numberKP) + " выход №" + Convert.ToString(packet.parametr)); break; case "off": // Получаем ссылку на экземпляр клиента clientinfo = TcpServer.ListOfClients.Find(ci => ci.Client.Equals(Client)); // Проверяем есть ли у пользователя права на телеуправление if (TcpServer.ListOfUsers.FindIndex( name => name == Convert.ToString(packet.nameClient)) == -1) { // Запись в лог-файл Loger.WriteToFile("Клиент '" + clientinfo.Name + "' (ip: " + clientinfo.IpAdress + ") заблокирована операция ТУ. Снять напряжение c КП №" + Convert.ToString(packet.numberKP) + " выход №" + Convert.ToString(packet.parametr) + "Причина: нет прав на телеуправление."); break; } // Добавить операцию телеуправления в список команд NevodCommand offCmd = new NevodCommand("off", packet.numberKP, packet.parametr); DataServer.hendCommmands.Add(offCmd); DataServer.WaitHandler.Set(); // Запись в лог-файл Loger.WriteToFile("Клиент '" + clientinfo.Name + "' (ip: " + clientinfo.IpAdress + ") запустил операцию ТУ. Снять напряжение c КП №" + Convert.ToString(packet.numberKP) + " выход №" + Convert.ToString(packet.parametr)); break; default: break; } } } // Получаем ссылку на экземпляр клиента ClientInfo cinfo = TcpServer.ListOfClients.Find(ci => ci.Client.Equals(Client)); // Запись в лог-файл Loger.WriteToFile("Отключился клиент '" + cinfo.Name + "' (ip: " + cinfo.IpAdress + ") ..."); // Удаляем клиента из списка подписчиков TcpServer.ListOfClients.Remove(TcpServer.ListOfClients.Find(ci => ci.Client.Equals(Client))); // Закрываем соединение Client.Close(); } catch (Exception exp) { Console.WriteLine(TcpServer.ListOfClients.Count); //for (int i = 0; i < TcpServer.ListOfClients.Count; i++) // if (TcpServer.ListOfClients[i].Client == Client) // { // // Получаем ссылку на экземпляр клиента // ClientInfo cinfo = TcpServer.ListOfClients.Find(ci => ci.Client.Equals(Client)); // // Запись в лог-файл // Loger.WriteToFile("Потеряно соединение с клиентом '" + cinfo.Name + // "' (ip: " + cinfo.IpAdress + ") ..."); // // Удаляем клиента из списка // TcpServer.ListOfClients.RemoveAt(i); // } // Получаем ссылку на экземпляр клиента ClientInfo cinfo = TcpServer.ListOfClients.Find(ci => ci.Client.Equals(Client)); // Запись в лог-файл Loger.WriteToFile("Потеряно соединение с клиентом '" + cinfo.Name + "' (ip: " + cinfo.IpAdress + ") ..."); // Удаляем экземпляр клиента из списка TcpServer.ListOfClients.Remove(cinfo); Console.WriteLine(TcpServer.ListOfClients.Count); Loger.SendMsg((int)MessagerId.Log, (int)MessagerId.TcpServer, exp.Message); } }
/// <summary> /// Отправить команду вручную /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonSend_Click(object sender, EventArgs e) { // Добавить новую команду в очередь NevodCommand tempCmd = new NevodCommand(); tempCmd.Cmd = textBoxCMD.Text + "\r"; tempCmd.NumberKP = -1; DataServer.hendCommmands.Add(tempCmd); // Возобновить поток опроса, если необходимо DataServer.WaitHandler.Set(); }
/// <summary> /// Телеуправление. Управляет напряжением выходов /// </summary> /// <param name="number">номер выхода: 0-7</param> /// <param name="value">действие: включить/выключить</param> public void Switch(int number) { // Указать, что запущенна новая команда InWork.Reset(); try { byte[] buf = new byte[256]; // Чтобы задать значение для нулевого бита нужно указать 8 // иначе комманда будет воспринята как общая "00" if (number == 0) number = 8; // #1013FF - включение DIO4 модуля string s = "#" + AddZero(Convert.ToString(_dgKpNum)) + AddZero(Convert.ToString(number)) + "01" + "\r"; byte[] queryOn = Encoding.ASCII.GetBytes(s); Communicators.comPort.Write(queryOn, 0, queryOn.Length); Loger.SendMsg((int)MessagerId.Log, (int)MessagerId.DataServer, ConvertByteMass(queryOn, queryOn.Length)); // Запись в лог-файл Loger.WriteToFile("Модуль №" + Convert.ToString(_dgKpNum) + ". Подать напряжение на выход №" + number); // Ждем пока появится сгнал // отработки цепей СДТУ "У" Thread.Sleep(700); Communicators.comPort.Read(buf, 0, 255); // Обновляем значения переменных AllVariablesRefresh(true); // Задержка перед выключением агригата Thread.Sleep(TimeoutTU); // #101300 - выключение DIO4 модуля byte[] queryOff = Encoding.ASCII.GetBytes("#" + AddZero(Convert.ToString(_dgKpNum)) + "0000\r"); Communicators.comPort.Write(queryOff, 0, queryOff.Length); Loger.SendMsg((int)MessagerId.Log, (int)MessagerId.DataServer, "RX: " + ConvertByteMass(queryOff, queryOff.Length)); // Запись в лог-файл Loger.WriteToFile("Модуль №" + Convert.ToString(_dgKpNum) + ". Снять напряжение с выхода №" + +number); Thread.Sleep(700); Communicators.comPort.Read(buf, 0, 255); } catch (Exception exp) { try { Loger.SendMsg((int)MessagerId.Log, (int)MessagerId.DataServer, "Ошибка телеуправления: " + exp.Message); // Обновляем значения переменных AllVariablesRefresh(true); // Проверяем, не остался ли какой-то агрегат включенным int numberOut = -1; if (_DgOut1 == true) numberOut = 0; if (_DgOut2 == true) numberOut = 1; if (_DgOut3 == true) numberOut = 2; if (_DgOut4 == true) numberOut = 3; if (_DgOut5 == true) numberOut = 4; if (_DgOut6 == true) numberOut = 5; if (_DgOut7 == true) numberOut = 6; if (_DgOut8 == true) numberOut = 7; // Если необходимо повторно пытаемя выключить агрегат if (numberOut != -1) { Loger.SendMsg((int)MessagerId.Log, (int)MessagerId.DataServer, "Повторная попытка отключения агрегата"); NevodCommand offCmd = new NevodCommand("off", _dgKpNum, numberOut); DataServer.hendCommmands.Add(offCmd); DataServer.WaitHandler.Set(); } } catch { } } // Обновляем значения переменных Thread.Sleep(TimeoutAfterTU); AllVariablesRefresh(true); // Указать, что команда закончена. InWork.Set(); }