Exemplo n.º 1
0
        /// <summary>
        /// Receives an identification packet.
        /// </summary>
        protected bool ReceiveHelloPacket(TcpConnection conn, out string helloStr, out string helloHex)
        {
            Log.WriteAction(Locale.IsRussian ?
                            "Приём идентификационного пакета данных от клиента {0}" :
                            "Receive an identification packet from the client {0}", conn.RemoteAddress);

            int readCnt = conn.ReadAvailable(inBuf, 0, HelloPacketLength, ProtocolFormat.String, out string logText);

            Log.WriteLine(logText);

            if (readCnt > 0)
            {
                helloStr = conn.Encoding.GetString(inBuf, 0, readCnt);
                helloHex = "0x" + ScadaUtils.BytesToHex(inBuf, 0, readCnt);
                return(true);
            }
            else
            {
                helloStr = "";
                helloHex = "";
                return(false);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Makes the communication channel ready for operating.
        /// </summary>
        public override void MakeReady()
        {
            CheckBehaviorSupport();

            if (options.ConnectionMode == ConnectionMode.Individual)
            {
                indivConnList = new List <TcpConnection>();
                DeviceDictionary deviceDict = new DeviceDictionary();
                deviceDict.AddRange(LineContext.SelectDevices());

                foreach (DeviceDictionary.DeviceGroup deviceGroup in deviceDict.SelectDeviceGroups())
                {
                    TcpConnection conn = new TcpConnection(Log, new TcpClient())
                    {
                        ReconnectAfter = options.ReconnectAfter
                    };

                    indivConnList.Add(conn);

                    foreach (DeviceLogic deviceLogic in deviceGroup)
                    {
                        conn.BindDevice(deviceLogic);
                        deviceLogic.Connection = conn;
                    }
                }
            }
            else // ConnectionMode.Shared
            {
                sharedConn = new TcpConnection(Log, new TcpClient())
                {
                    ReconnectAfter = options.ReconnectAfter
                };

                SetDeviceConnection(sharedConn);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Communication cycle running in a separate thread.
        /// </summary>
        protected void Execute()
        {
            int      threadDelay    = options.Behavior == ChannelBehavior.Slave ? SlaveThreadDelay : ScadaUtils.ThreadDelay;
            TimeSpan clientLifetime = TimeSpan.FromSeconds(options.ClientLifetime);

            while (!terminated)
            {
                TcpConnection conn = null;

                try
                {
                    // open incoming connections
                    while (tcpListener.Pending() && !terminated)
                    {
                        Log.WriteAction(Locale.IsRussian ?
                                        "Соединение с клиентом {0}" :
                                        "Connect to the client {0}", conn.RemoteAddress);
                        conn = new TcpConnection(Log, tcpListener.AcceptTcpClient());

                        if (options.ConnectionMode == ConnectionMode.Shared)
                        {
                            BindDevices(conn, LineContext.SelectDevices());
                        }
                        else if (options.DeviceMapping == DeviceMapping.ByIPAddress)
                        {
                            if (deviceDict.GetDeviceGroup(conn.RemoteAddress,
                                                          out DeviceDictionary.DeviceGroup deviceGroup))
                            {
                                BindDevices(conn, deviceGroup);
                            }
                            else
                            {
                                Log.WriteError(CommPhrases.UnableFindDevice, conn.RemoteAddress);
                                conn.CloseMark = true;
                            }
                        }

                        lock (connList)
                        {
                            connList.Add(conn);
                        }
                    }

                    // receive data from connected clients
                    DateTime utcNow  = DateTime.UtcNow;
                    int      connIdx = 0;

                    while (connIdx < connList.Count && !terminated)
                    {
                        conn = connList[connIdx];

                        lock (conn)
                        {
                            // receive available data
                            if (conn.TcpClient.Available > 0 && !conn.CloseMark)
                            {
                                ReceiveData(conn);
                            }

                            // close inactive connection
                            if (utcNow - conn.ActivityTime > clientLifetime || conn.CloseMark)
                            {
                                Log.WriteAction(Locale.IsRussian ?
                                                "Отключение клиента {0}" :
                                                "Disconnect the client {0}", conn.RemoteAddress);
                                conn.Close();

                                lock (connList)
                                {
                                    connList.RemoveAt(connIdx);
                                }
                            }
                            else
                            {
                                connIdx++;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (conn == null)
                    {
                        Log.WriteException(ex, Locale.IsRussian ?
                                           "Ошибка при взаимодействии с клиентами" :
                                           "Error communicating with clients");
                    }
                    else
                    {
                        Log.WriteException(ex, Locale.IsRussian ?
                                           "Ошибка при взаимодействии с клиентом {0}" :
                                           "Error communicating with the client {0}", conn.RemoteAddress);
                    }
                }
                finally
                {
                    Thread.Sleep(threadDelay);
                }
            }
        }