C# - опрос устройства по TCP / IP - PullRequest
0 голосов
/ 29 мая 2020

Я попытался опросить устройство по протоколу Modbus для TCP / IP, и он работает хорошо, но есть проблемы.

Если я запустил этот код на слабом компьютере, время отклика увеличится и очень много ... Разница в скорости опроса примерно 6 секунд.

Например - я отправляю запрос на свой компьютер 01 03 04 50 00 01 85 2B и получаю ответ через 0.057 секунд, а на более слабом компьютере это запрос получен за 0.560 секунд. Ответ тот же 01 03 02 02 C1 78 B4. Устройство такое же и подключается точно так же.

public override void Run()
    {
        IsRunning = true;
        OnJobStarted?.Invoke(this);
        OnLogMessage?.Invoke(this, "JOB START");
        try
        {
            while (Job.ThreadState == ThreadState.Running && !isJobTerminated)
            {
                var ts = DateTime.Now;
                if (!Ping())
                {

                }
                var es = DateTime.Now;
                var ms = (es - ts).TotalMilliseconds;
                while (!isJobTerminated && (DateTime.Now - ts).TotalMilliseconds <= this.PingInterval * 1000)
                    Thread.Sleep(10);
            }
        }
        catch (Exception ex)
        {
            OnLogMessage?.Invoke(this, " RUN: " + ex.Message);
        }
        OnLogMessage?.Invoke(this, "JOB END");
        OnJobEnded?.Invoke(this);
        IsRunning = false;
    }

.

public override bool Ping()
    {
        var result = false;
        try
        {
            PingStat.LastPingDateTime = DateTime.Now;
            PingStat.PingInterval = this.PingInterval;

            result = true;
            PingStat.TotalPingCount++;
            if (!result)
                PingStat.ErrorCount++;

            if (result)
            {
                foreach (var md in Children.Where(m => !m.IsSuspended && m.IsEnabled))
                {
                    var pingResult = ReadConfiguration(md).ErrorCode == 0;
                    Thread.Sleep(10);

                    if (pingResult)
                        ReadState(md);
                    if (pingResult && md.IsMaskChanged)
                    {
                        var maskResult = WriteSingleRegister(md, 0x05FC, md.Mask);
                        md.IsMaskChanged = !(maskResult.ErrorCode == 0);
                    }

                    md.PingStat.IsLastPingOk = pingResult;
                    md.OnPing?.Invoke(md, pingResult);

                }
            }
        }
        catch (Exception ex)
        {
            OnLogMessage?.Invoke(this, ex.Message + Environment.NewLine + ex.StackTrace);
            result = false;
        }
        finally
        {
            PingStat.IsLastPingOk = result;
            OnPing?.Invoke(this, result);
        }
        return result;
    }

.

public override RcResult ExecuteModBus(RcModBusDevice device, byte[] request, out byte[] answer)
    {
        answer = null;
        var result = new RcResult();
        var dt = DateTime.Now;
        Random rnd = new Random();
        try
        {
            OnLogMessage?.Invoke(this, "ExecuteModBus Lock?");
            lock (communication)
            {

                OnLogMessage?.Invoke(this, "ExecuteModBus Lock!");

                using (var tcpClient = new TcpClient())
                {
                    tcpClient.Connect(IP, Port);
                    tcpClient.SendTimeout = SendTimeout;
                    tcpClient.ReceiveTimeout = Math.Max(100, ReceiveTimeout);
                    using (var stream = tcpClient.GetStream())
                    {
                        dt = DateTime.Now;
                        OnLogMessage?.Invoke(this, "REQUEST->:" + Utils.BytesToHex(request));
                        stream.Write(request, 0, request.Length);

                        var tmp = new byte[0xA0];
                        int dataLength = 0;

                        try
                        {

                            for (dataLength = 0; dataLength < tmp.Length; dataLength++)
                            {
                                tmp[dataLength] = (byte)(stream.ReadByte());
                                tcpClient.ReceiveTimeout = 100 - Properties.Settings.Default.coefIP;
                                Thread.Sleep(0);
                            }

                        }
                        catch (Exception ex)
                        {
                        }

                        if (dataLength < 2)
                            result.ErrorCode = 1;
                        else
                        {
                            var crc = Utils.GetCRC(tmp, 0, dataLength - 2);
                            if (crc[0] != tmp[dataLength - 2] || crc[1] != tmp[dataLength - 1])
                            {
                                result.ErrorCode = 1;
                                result.ErrorText = "Bad CRC";
                            }
                        }
                        answer = new byte[dataLength];
                        Array.Copy(tmp, 0, answer, 0, dataLength);
                    }
                    OnLogMessage?.Invoke(this, "ANSWER<-:" + Utils.BytesToHex(answer));
                    if (device != null)
                        SaveToLog(DbID, device.DbID, dt, Utils.BytesToHex(request), DateTime.Now, Utils.BytesToHex(answer));
                }
            }
            OnLogMessage?.Invoke(this, "ExecuteModBus UnLock");
        }
        catch (Exception ex)
        {
            SaveToLog(DbID, device.DbID, dt, Utils.BytesToHex(request), DateTime.Now, "ERROR", ex.Message);
            OnLogMessage?.Invoke(this, ex.Message + Environment.NewLine + ex.StackTrace);
            result = new RcResult() { ErrorCode = 1, ErrorText = ex.Message };
        }
        return result;
    }
...