/// <summary> /// Остановить работу канала связи /// </summary> public override void Stop() { try { // остановка потока приёма данных в режиме ведомого StopThread(); } finally { if (settings.ConnMode == ConnectionModes.Shared) { // закрытие общего соединения sharedTcpConn.Close(); // очистка ссылки на соединение для всех КП на линии связи foreach (KPLogic kpLogic in kpList) { kpLogic.Connection = null; } } else { // закрытие всех соединений, обнуление ссылок на соединение для КП foreach (TcpConnection tcpConn in tcpConnList) { tcpConn.Close(); } tcpConnList = null; // вызов метода базового класса base.Stop(); } } }
/// <summary> /// Цикл взаимодействия с TCP-клиентами (метод вызывается в отдельном потоке) /// </summary> protected void Execute() { // сохранение в локальных переменных постоянно используемых значений int inactiveTime = settings.InactiveTime; bool devSelByIPAddress = settings.DevSelMode == DeviceSelectionModes.ByIPAddress; int threadDelay = slaveBehavior ? SlaveThreadDelay : MasterThreadDelay; // выбор метода обработки доступных данных Action<TcpConnection> procAvailableData; if (sharedConnMode) procAvailableData = ProcAvailableDataShared; else procAvailableData = ProcAvailableDataIndiv; // цикл взаимодействия с TCP-клиентами while (!terminated) { TcpConnection tcpConn = null; try { lock (tcpConnList) { // открытие запрашиваемых соединений while (tcpListener.Pending() && !terminated) { TcpClient tcpClient = tcpListener.AcceptTcpClient(); tcpConn = new TcpConnection(tcpClient); tcpConn.WriteToLog = WriteToLog; WriteToLog(string.Format(Localization.UseRussian ? "{0} Соединение с клиентом {1}" : "{0} Connect to the client {1}", CommUtils.GetNowDT(), tcpConn.RemoteAddress)); tcpConnList.Add(tcpConn); // установка соединения всем КП if (sharedConnMode) SetConnectionToAllKPs(tcpConn); // привязка соединения к КП по IP-адресу else if (devSelByIPAddress && !BindConnByIP(tcpConn)) tcpConn.Broken = true; } // работа с открытыми соединениями DateTime nowDT = DateTime.Now; int connInd = 0; while (connInd < tcpConnList.Count && !terminated) { tcpConn = tcpConnList[connInd]; // приём и обработка данных от TCP-клиента if (tcpConn.TcpClient.Available > 0) procAvailableData(tcpConn); // закрытие соединения, если оно неактивно if ((nowDT - tcpConn.ActivityDT).TotalSeconds > inactiveTime || tcpConn.Broken) { WriteToLog(string.Format(Localization.UseRussian ? "{0} Отключение клиента {1}" : "{0} Disconnect the client {1}", nowDT.ToString(CommUtils.CommLineDTFormat), tcpConn.RemoteAddress)); tcpConn.Close(); tcpConnList.RemoveAt(connInd); } else { connInd++; } } } } catch (Exception ex) { if (tcpConn == null) WriteToLog(string.Format(Localization.UseRussian ? "Ошибка при взаимодействии с клиентами: {0}" : "Error communicating with clients: {0}", ex.Message)); else WriteToLog(string.Format(Localization.UseRussian ? "Ошибка при взаимодействии с клиентом {0}: {1}" : "Error communicating with the client {0}: {1}", tcpConn.RemoteAddress, ex.Message)); } Thread.Sleep(threadDelay); } }
/// <summary> /// Цикл взаимодействия с TCP-клиентами (метод вызывается в отдельном потоке) /// </summary> protected void Execute() { // сохранение в локальных переменных постоянно используемых значений int inactiveTime = settings.InactiveTime; bool devSelByIPAddress = settings.DevSelMode == DeviceSelectionModes.ByIPAddress; int threadDelay = slaveBehavior ? SlaveThreadDelay : MasterThreadDelay; // выбор метода обработки доступных данных Action <TcpConnection> procAvailableData; if (sharedConnMode) { procAvailableData = ProcAvailableDataShared; } else { procAvailableData = ProcAvailableDataIndiv; } // цикл взаимодействия с TCP-клиентами while (!terminated) { TcpConnection tcpConn = null; try { lock (tcpConnList) { // открытие запрашиваемых соединений while (tcpListener.Pending() && !terminated) { TcpClient tcpClient = tcpListener.AcceptTcpClient(); tcpConn = new TcpConnection(tcpClient); tcpConn.WriteToLog = WriteToLog; WriteToLog(string.Format(Localization.UseRussian ? "{0} Соединение с клиентом {1}" : "{0} Connect to the client {1}", CommUtils.GetNowDT(), tcpConn.RemoteAddress)); tcpConnList.Add(tcpConn); // установка соединения всем КП if (sharedConnMode) { SetConnectionToAllKPs(tcpConn); } // привязка соединения к КП по IP-адресу else if (devSelByIPAddress && !BindConnByIP(tcpConn)) { tcpConn.Broken = true; } } // работа с открытыми соединениями DateTime nowDT = DateTime.Now; int connInd = 0; while (connInd < tcpConnList.Count && !terminated) { tcpConn = tcpConnList[connInd]; // приём и обработка данных от TCP-клиента if (tcpConn.TcpClient.Available > 0) { procAvailableData(tcpConn); } // закрытие соединения, если оно неактивно if ((nowDT - tcpConn.ActivityDT).TotalSeconds > inactiveTime || tcpConn.Broken) { WriteToLog(string.Format(Localization.UseRussian ? "{0} Отключение клиента {1}" : "{0} Disconnect the client {1}", nowDT.ToString(CommUtils.CommLineDTFormat), tcpConn.RemoteAddress)); tcpConn.Close(); tcpConnList.RemoveAt(connInd); } else { connInd++; } } } } catch (Exception ex) { if (tcpConn == null) { WriteToLog(string.Format(Localization.UseRussian ? "Ошибка при взаимодействии с клиентами: {0}" : "Error communicating with clients: {0}", ex.Message)); } else { WriteToLog(string.Format(Localization.UseRussian ? "Ошибка при взаимодействии с клиентом {0}: {1}" : "Error communicating with the client {0}: {1}", tcpConn.RemoteAddress, ex.Message)); } } Thread.Sleep(threadDelay); } }