Ejemplo n.º 1
0
        /// <summary>
        /// 将命令发送到发送缓冲区
        /// </summary>
        /// <param name="Address">
        /// 地址:
        /// 作为下行通信协议,应填写设备的硬件地址
        /// 作为上行通信协议,可不填
        /// </param>
        /// <param name="AFN">功能码</param>
        /// <param name="DataArea">
        /// 包括帧头、帧尾(但不包括校验)的完整报文数据
        /// important:根据协议的具体实现有所不同
        /// </param>
        /// <param name="NeedReply">该报文是否需要回复</param>
        /// <param name="IPAddr">
        /// 通信数据目标的IP地址:仅供TCP Server通信方式使用
        /// </param>
        /// <param name="sync">
        /// 用于同步通信的通信状态控制:比如用于顺序发送文件等。平常的数据通信不使用此重载
        /// </param>
        /// <returns></returns>
        public virtual bool Main_SendToCache(int Address, int AFN, byte[] DataArea, bool NeedReply, string IPAddr,
                                             ref ProtocolSyncStatus sync)
        {
            /// 通信未连接则不发送到缓冲区
            if (!this.m_Comm.Connected)
            {
                return(false);
            }

            ProtocolFrameStruct se1 = new ProtocolFrameStruct(Address, AFN);

            SyncStatus.Success = false;

            try
            {
                se1.DataArea  = DataArea;
                se1.NeedReply = NeedReply;
                se1.IPAddr    = IPAddr;

                se1.WaitingFlag = false;
                se1.ResendCount = 0;

                lock (SendCacheLock)
                {
                    SendCache.Enqueue(se1);
                }

                sync = SyncStatus;
                return(true);
            }
            catch
            {
                return(false);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 完全克隆一个协议帧
        /// </summary>
        /// <returns></returns>
        public ProtocolFrameStruct Clone()
        {
            ProtocolFrameStruct item = (ProtocolFrameStruct)this.MemberwiseClone();

            // 因为数组是对象,浅表副本只复制引用,所以要处理一下
            byte[] data = (byte[])this.DataArea.Clone();
            item.DataArea = data;
            return(item);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 将一个完整的接收报文发送到接收缓冲区等待处理
        /// </summary>
        /// <param name="Address">
        /// 地址:
        /// 作为下行通信协议,应填写设备的硬件地址
        /// 作为上行通信协议,应填写RTU的站地址
        /// </param>
        /// <param name="AFN">功能码</param>
        /// <param name="DataArea">包括帧头、帧尾(但不包括校验)的完整报文数据</param>
        /// <param name="IPAddr">
        /// 通信数据目标的IP地址:仅供TCP Server通信方式使用
        /// </param>
        /// <returns></returns>
        public virtual bool Main_RecvToCache(int Address, int AFN, byte[] DataArea, string IPAddr)
        {
            ProtocolFrameStruct re1 = new ProtocolFrameStruct(Address, AFN);

            try
            {
                re1.DataArea = DataArea;
                re1.IPAddr   = IPAddr;

                lock (RecvCacheLock)
                {
                    RecvCache.Enqueue(re1);
                }

                return(true);
            }
            catch
            {
                return(false);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 标准的通信协议发送处理驱动
        /// </summary>
        public virtual void Main_CommDriver_Send()
        {
            try
            {
                // 将发送缓冲区中的第一个命令发送出去
                if (SendCache.Count > 0)
                {
                    se = SendCache.Peek();
                    if (se.WaitingFlag)
                    {
                        //当前命令已经发送,正在等待
                        Main_CommDriver_Resend();
                    }
                    else
                    {
                        //发送一个新的命令
                        se.SendTick = HyTick.TickTimeGet();
                        Main_SendCmd();

                        if (se.NeedReply)
                        {
                            // 需要等待回复的报文:应该置标志并等待接收、重发等处理
                            se.WaitingFlag = true;
                        }
                        else
                        {
                            // 不需要等待回复的报文:应该直接从发送缓冲区清除
                            lock (SendCacheLock)
                            {
                                SendCache.Dequeue();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //System.Windows.Forms.MessageBox.Show("方法Main_CommDriver_Send()出现了错误!" + ex.Message);
            }
        }
Ejemplo n.º 5
0
 /// <summary>
 /// 标准的通信协议接收处理驱动
 /// </summary>
 public virtual void Main_CommDriver_Recv()
 {
     try
     {
         // 把接收缓冲区中所有的报文都处理完
         while (RecvCache.Count > 0)
         {
             re = RecvCache.Peek();
             if (Frame_Analysis())
             {
                 ///协议通信正常
                 if (m_HardAddress != null)
                 {
                     if (m_HardAddress.ContainsKey(re.Address))
                     {
                         m_HardAddress[re.Address].ErrorCount = 0;
                         m_HardAddress[re.Address].CommStatus = true;
                     }
                 }
                 else
                 {
                     this.m_CommStatus = true;
                     this.m_ErrorCount = 0;
                 }
             }
             else
             {
             }
             lock (RecvCacheLock)
             {
                 RecvCache.Dequeue();
             }
         }
     }
     catch (Exception ex)
     {
         //System.Windows.Forms.MessageBox.Show("方法Main_CommDriver_Recv()出现了错误!" + ex.Message);
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// 标准的通信协议轮询处理驱动
        /// </summary>
        public virtual void Polling_Driver()
        {
            try
            {
                /// 通信未连接则不进行轮询
                if (!this.m_Comm.Connected)
                {
                    return;
                }

                // 定时把轮询的报文发送到发送缓冲区中
                if (this.PollingList.Count == 0)
                {
                    return;
                }

                // 若发送缓冲区非空,则意味着前次的轮询未完或者有命令正在处理,目前可以不轮询
                if (SendCache.Count > 0)
                {
                    return;
                }

                if (this.m_PollingIndex == 0)
                {
                    ///表示要开始一次新的轮询周期

                    if (m_TimeDifferenceCalcFlag_Polling)
                    {
                        m_TimeDifferenceCalcFlag_Polling = false;
                        //记录上次轮询所花费的时间
                        this.m_LastPollingPeriod = HyTick.TickTimeDifference(this.m_PollingTick, HyTick.TickTimeGet());
                        if (this.m_MinPollingPeriod > this.m_LastPollingPeriod)
                        {
                            this.m_MinPollingPeriod = this.m_LastPollingPeriod;
                        }
                    }

                    if (!HyTick.TickTimeIsArrived(this.m_PollingTick, this.m_PollingInterval))
                    {
                        return;
                    }
                    ///记录本次轮询周期开始的时刻
                    this.m_PollingTick = HyTick.TickTimeGet();
                    m_TimeDifferenceCalcFlag_Polling = true;
                }

                // 现在可以把当前的一个轮询报文发送到缓冲区
                ProtocolFrameStruct pl = PollingList[this.m_PollingIndex].Clone();
                pl.NeedReply   = true;
                pl.ResendCount = 0;
                pl.WaitingFlag = false;
                lock (SendCacheLock)
                {
                    SendCache.Enqueue(pl);
                    this.m_PollingIndex++;
                    this.m_PollingIndex %= PollingList.Count;
                }
            }
            catch (Exception ex)
            {
                //System.Windows.Forms.MessageBox.Show("方法Polling_Driver()出现了错误!" + ex.Message);
            }
        }