Пример #1
0
 /// <summary>
 /// Конструктор
 /// </summary>
 public CommTcpClientLogic()
     : base()
 {
     settings = new Settings();
     tcpConnList = null;
     sharedTcpConn = null;
 }
Пример #2
0
        /// <summary>
        /// Остановить работу канала связи
        /// </summary>
        public override void Stop()
        {
            try
            {
                // остановка потока взаимодействия с клиентами
                StopThread();
            }
            finally
            {
                try
                {
                    // остановка прослушивателя соединений
                    if (tcpListener != null)
                    {
                        tcpListener.Stop();
                        tcpListener = null;
                        WriteToLog("");
                        WriteToLog(string.Format(Localization.UseRussian ?
                                                 "{0} Прослушиватель соединений остановлен" :
                                                 "{0} Connection listener is stopped", CommUtils.GetNowDT()));
                    }
                }
                finally
                {
                    // отключение всех клиентов
                    lock (tcpConnList)
                    {
                        foreach (TcpConnection tcpConn in tcpConnList)
                        {
                            tcpConn.Close();
                        }
                        tcpConnList.Clear();
                        sharedTcpConn = null;
                    }

                    // вызов метода базового класса
                    base.Stop();
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Инициализировать канал связи
        /// </summary>
        public override void Init(SortedList <string, string> commCnlParams, List <KPLogic> kpList)
        {
            // вызов метода базового класса
            base.Init(commCnlParams, kpList);

            // инициализация настроек канала связи
            settings.Init(commCnlParams);

            // создание соединений и установка соединений КП
            if (settings.ConnMode == ConnectionModes.Shared)
            {
                // общее соединение для всех КП
                sharedTcpConn = new TcpConnection(new TcpClient());
                sharedTcpConn.ReconnectAfter = settings.ReconnectAfter;

                foreach (KPLogic kpLogic in kpList)
                {
                    kpLogic.Connection = sharedTcpConn;
                }
            }
            else
            {
                // индивидуальное соединение для каждого КП или группы КП с общим позывным
                tcpConnList = new List <TcpConnection>();
                foreach (List <KPLogic> kpByCallNumList in kpCallNumDict.Values)
                {
                    foreach (KPLogic kpLogic in kpByCallNumList)
                    {
                        TcpConnection tcpConn = new TcpConnection(new TcpClient());
                        tcpConn.ReconnectAfter = settings.ReconnectAfter;
                        tcpConnList.Add(tcpConn);
                        tcpConn.AddRelatedKP(kpLogic);
                        kpLogic.Connection = tcpConn;
                    }
                }
            }

            // проверка поддержки режима работы канала связи подключенными КП
            CheckBehaviorSupport();
        }
Пример #4
0
        /// <summary>
        /// Цикл приёма данных по индивидуальным соединениям в режиме ведомого (метод вызывается в отдельном потоке)
        /// </summary>
        protected void ListenIndividualConn()
        {
            try
            {
                while (!terminated)
                {
                    foreach (KPLogic kpLogic in kpList)
                    {
                        TcpConnection tcpConn = kpLogic.Connection as TcpConnection;

                        if (tcpConn != null && tcpConn.TcpClient.Available > 0)
                        {
                            KPLogic targetKP = kpLogic;
                            if (!ExecProcUnreadIncomingReq(kpLogic, tcpConn, ref targetKP))
                            {
                                sharedTcpConn.ClearNetStream(inBuf);
                            }
                        }
                    }

                    Thread.Sleep(SlaveThreadDelay);
                }
            }
            catch (Exception ex)
            {
                // данное исключение возникать не должно
                if (Localization.UseRussian)
                {
                    WriteToLog("Ошибка при приёме данных по индивидуальным соединениям: " + ex.Message);
                    WriteToLog("Приём данных прекращён");
                }
                else
                {
                    WriteToLog("Error receiving data via individual connections: " + ex.Message);
                    WriteToLog("Data receiving is terminated");
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Выполнить действия перед сеансом опроса КП или отправкой команды
        /// </summary>
        public override void BeforeSession(KPLogic kpLogic)
        {
            // установка соединения при необходимости
            TcpConnection tcpConn = kpLogic.Connection as TcpConnection;

            if (tcpConn != null && !tcpConn.Connected)
            {
                try
                {
                    // определение IP-адреса и TCP-порта
                    IPAddress addr;
                    int       port;

                    if (tcpConn == sharedTcpConn)
                    {
                        addr = IPAddress.Parse(settings.IpAddress);
                        port = settings.TcpPort;
                    }
                    else
                    {
                        CommUtils.ExtractAddrAndPort(kpLogic.CallNum, settings.TcpPort, out addr, out port);
                    }

                    // установка соединения
                    WriteToLog("");
                    WriteToLog(string.Format(Localization.UseRussian ?
                                             "{0} Установка TCP-соединения с {1}:{2}" :
                                             "{0} Establish a TCP connection with {1}:{2}", CommUtils.GetNowDT(), addr, port));
                    tcpConn.Open(addr, port);
                }
                catch (Exception ex)
                {
                    WriteToLog(ex.Message);
                }
            }
        }
Пример #6
0
        /// <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);
            }
        }
Пример #7
0
        /// <summary>
        /// Установить соединение всем КП на линии связи
        /// </summary>
        protected void SetConnectionToAllKPs(TcpConnection tcpConn)
        {
            if (sharedTcpConn != null)
                sharedTcpConn.Broken = true;

            sharedTcpConn = tcpConn;
            foreach (KPLogic kpLogic in kpList)
                kpLogic.Connection = sharedTcpConn;
        }
Пример #8
0
        /// <summary>
        /// Остановить работу канала связи
        /// </summary>
        public override void Stop()
        {
            try
            {
                // остановка потока взаимодействия с клиентами
                StopThread();
            }
            finally
            {
                try
                {
                    // остановка прослушивателя соединений
                    if (tcpListener != null)
                    {
                        tcpListener.Stop();
                        tcpListener = null;
                        WriteToLog("");
                        WriteToLog(string.Format(Localization.UseRussian ? 
                            "{0} Прослушиватель соединений остановлен" :
                            "{0} Connection listener is stopped", CommUtils.GetNowDT()));
                    }
                }
                finally
                {
                    // отключение всех клиентов
                    lock (tcpConnList)
                    {
                        foreach (TcpConnection tcpConn in tcpConnList)
                            tcpConn.Close();
                        tcpConnList.Clear();
                        sharedTcpConn = null;
                    }

                    // вызов метода базового класса
                    base.Stop();
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Инициализировать канал связи
        /// </summary>
        public override void Init(SortedList<string, string> commCnlParams, List<KPLogic> kpList)
        {
            // вызов метода базового класса
            base.Init(commCnlParams, kpList);

            // инициализация настроек канала связи
            settings.Init(commCnlParams);

            // создание соединений и установка соединений КП
            if (settings.ConnMode == ConnectionModes.Shared)
            {
                // общее соединение для всех КП
                sharedTcpConn = new TcpConnection(new TcpClient());
                foreach (KPLogic kpLogic in kpList)
                    kpLogic.Connection = sharedTcpConn;
            }
            else
            {
                // индивидуальное соединение для каждого КП или группы КП с общим позывным
                tcpConnList = new List<TcpConnection>();
                foreach (List<KPLogic> kpByCallNumList in kpCallNumDict.Values)
                {
                    foreach (KPLogic kpLogic in kpByCallNumList)
                    {
                        int timeout = kpLogic.ReqParams.Timeout;
                        TcpConnection tcpConn = new TcpConnection(new TcpClient());
                        tcpConnList.Add(tcpConn);
                        tcpConn.AddRelatedKP(kpLogic);
                        kpLogic.Connection = tcpConn;
                    }
                }
            }

            // проверка поддержки режима работы канала связи подключенными КП
            CheckBehaviorSupport();
        }
Пример #10
0
 /// <summary>
 /// Привязать соединение к КП, используя библиотеку КП
 /// </summary>
 protected void BindConnByDeviceLibrary(TcpConnection tcpConn, KPLogic kpLogic)
 {
     if (kpLogic != null)
     {
         WriteToLog(string.Format(Localization.UseRussian ?
             "{0} Клиент {1} привязан к {2}, используя библиотеку КП" :
             "{0} The client {1} is bound to the {2} using a device library", 
             CommUtils.GetNowDT(), tcpConn.RemoteAddress, kpLogic.Caption));
         SetConnection(kpLogic, tcpConn);
     }
     else
     {
         WriteToLog(string.Format(Localization.UseRussian ?
             "{0} Не удалось привязать клиента {1} к КП, используя библиотеку КП" :
             "{0} Unable to bind the client {1} to a device using a device library",
             CommUtils.GetNowDT(), tcpConn.RemoteAddress));
     }
 }
Пример #11
0
        /// <summary>
        /// Принять первый пакет данных, содержащий позывной
        /// </summary>
        protected string ReceiveFirstPackage(TcpConnection tcpConn)
        {
            WriteToLog(string.Format(Localization.UseRussian ? 
                "{0} Приём первого пакета данных от клиента {1}" : 
                "{0} Receive the first data package from the client {1}",
                CommUtils.GetNowDT(), tcpConn.RemoteAddress));

            string logText;
            int readCnt = tcpConn.ReadAvailable(inBuf, 0, CommUtils.ProtocolLogFormats.String, out logText);
            WriteToLog(logText);

            return readCnt > 0 ? Encoding.Default.GetString(inBuf, 0, readCnt) : "";
        }
Пример #12
0
        /// <summary>
        /// Привязать соединение к КП по IP-адресу 
        /// </summary>
        protected bool BindConnByIP(TcpConnection tcpConn)
        {
            List<KPLogic> kpByCallNumList; // список КП с общим позывным
            string nowDTStr = CommUtils.GetNowDT();

            if (kpCallNumDict.TryGetValue(tcpConn.RemoteAddress, out kpByCallNumList))
            {
                foreach (KPLogic kpLogic in kpByCallNumList)
                {
                    WriteToLog(string.Format(Localization.UseRussian ?
                        "{0} Клиент {1} привязан к {2} по IP-адресу" :
                        "{0} The client {1} is bound to the {2} by IP address",
                        nowDTStr, tcpConn.RemoteAddress, kpLogic.Caption));
                    SetConnection(kpLogic, tcpConn);
                }
                return true;
            }
            else
            {
                WriteToLog(string.Format(Localization.UseRussian ?
                    "{0} Не удалось привязать клиента {1} к КП по IP-адресу" :
                    "{0} Unable to bind the client {1} to a device by IP address",
                    nowDTStr, tcpConn.RemoteAddress));
                return false;
            }
        }
Пример #13
0
        /// <summary>
        /// Привязать соединение к КП по позывному
        /// </summary>
        protected bool BindConnByFirstPackage(TcpConnection tcpConn, string firstPackage)
        {
            List<KPLogic> kpByCallNumList; // список КП с одинаковым позывным
            string nowDTStr = CommUtils.GetNowDT();

            if (kpCallNumDict.TryGetValue(firstPackage, out kpByCallNumList))
            {
                foreach (KPLogic kpLogic in kpByCallNumList)
                {
                    WriteToLog(string.Format(Localization.UseRussian ?
                        "{0} Клиент {1} привязан к {2} по первому пакету данных" :
                        "{0} The client {1} is bound to the {2} by first data package",
                        nowDTStr, tcpConn.RemoteAddress, kpLogic.Caption));
                    SetConnection(kpLogic, tcpConn);
                }
                return true;
            }
            else
            {
                WriteToLog(string.Format(Localization.UseRussian ?
                    "{0} Не удалось привязать клиента {1} к КП по первому пакету данных" :
                    "{0} Unable to bind the client {1} to a device by first data package",
                    nowDTStr, tcpConn.RemoteAddress));
                return false;
            }
        }
Пример #14
0
        /// <summary>
        /// Конструктор
        /// </summary>
        public CommTcpServerLogic()
            : base()
        {
            slaveBehavior = false;
            sharedConnMode = false;
            devSelByFirstPackage = false;
            devSelByDeviceLibrary = false;

            settings = new Settings();
            tcpListener = null;
            tcpConnList = new List<TcpConnection>();
            sharedTcpConn = null;
        }
Пример #15
0
        /// <summary>
        /// Установить соединение для КП
        /// </summary>
        protected void SetConnection(KPLogic kpLogic, TcpConnection tcpConn)
        {
            TcpConnection existingTcpConn = kpLogic.Connection as TcpConnection;
            if (existingTcpConn != null)
            {
                existingTcpConn.Broken = true;
                existingTcpConn.ClearRelatedKPs();
            }

            kpLogic.Connection = tcpConn;
            tcpConn.AddRelatedKP(kpLogic);
        }
Пример #16
0
 /// <summary>
 /// Обработать доступные данные в режиме соединения Shared
 /// </summary>
 protected void ProcAvailableDataShared(TcpConnection tcpConn)
 {
     // обработка входящего запроса в режиме ведомого для произвольного КП
     if (tcpConn == sharedTcpConn && slaveBehavior && firstKP != null)
     {
         KPLogic targetKP = null;
         if (!ExecProcUnreadIncomingReq(firstKP, tcpConn, ref targetKP))
             tcpConn.ClearNetStream(inBuf);
     }
 }
Пример #17
0
        /// <summary>
        /// Обработать доступные данные в режиме соединения Individual
        /// </summary>
        protected void ProcAvailableDataIndiv(TcpConnection tcpConn)
        {
            if (tcpConn.RelatedKPExists)
            {
                // обработка входящего запроса в режиме ведомого для первого КП из группы с одинаковым позывным
                if (slaveBehavior)
                {
                    KPLogic targetKP = tcpConn.GetFirstRelatedKP();
                    if (!ExecProcUnreadIncomingReq(targetKP, tcpConn, ref targetKP))
                        tcpConn.ClearNetStream(inBuf);
                }
            }
            else
            {
                // привязка соединения к КП по первому пакету данных
                if (devSelByFirstPackage)
                {
                    if (tcpConn.JustConnected)
                    {
                        string firstPackage = ReceiveFirstPackage(tcpConn);
                        if (!BindConnByFirstPackage(tcpConn, firstPackage))
                            tcpConn.Broken = true;
                    }
                }
                else if (devSelByDeviceLibrary)
                {
                    // привязка соединения к КП, используя произвольную библиотеку КП
                    if (kpListNotEmpty)
                    {
                        KPLogic targetKP = null;
                        if (!ExecProcUnreadIncomingReq(firstKP, tcpConn, ref targetKP))
                            tcpConn.ClearNetStream(inBuf);
                        BindConnByDeviceLibrary(tcpConn, targetKP);
                    }
                }
            }

            tcpConn.JustConnected = false;
        }
Пример #18
0
        /// <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);
            }
        }