示例#1
0
        //数据包处理函数
        private void PacketHandler(SerialRecvMsg recvMsg)
        {
            if (recvMsg.PacketData.PacketIsAck())                       //判断是否是响应数据包, 若是响应, 则将其从重发字典中移除
            {
                recvMsg.PacketData.generateSendUType();
                string key = recvMsg.PacketData.SendUType;
                if (key != null)
                {
                    lock (resendDic)
                    {
                        if (resendDic.ContainsKey(key))
                        {
                            resendDic.Remove(key);
                        }
                    }
                }
            }

                        #if DEBUG                     //将发送消息投入调试接收队列中
            if (SerialComDebug.isPauseDebug == false) //若当前不是暂停状态
            {
                recvMsg.RecvTime = DateTime.Now;      //记录时间
                this.DebugQueue_Enqueue(recvMsg);
            }
                        #endif

            recvMsg.IsFromExtern = true;                        //外部消息
            this.RecvQueue_Enqueue(recvMsg);                    //投入接收消息队列中
        }
示例#2
0
        //串口数据接收状态机
        private void RecvPacketStateMachine(byte RecvByte)
        {
            switch (CurrentRecvState)
            {
            case RECVPACKSTATE.IdleState:                                       //空闲态
                if (RecvByte == (byte)0x5A)
                {
                    CurrentRecvState = RECVPACKSTATE.StartFieldState;
                }
                else
                {
                    CurrentRecvState = RECVPACKSTATE.IdleState;
                }
                break;

            case RECVPACKSTATE.StartFieldState:                                 //接收起始符
                if (RecvByte == (byte)0xA5)
                {
                    CurrentRecvState = RECVPACKSTATE.DataPacketState;
                    DataCnt          = 0;
                }
                else
                {
                    CurrentRecvState = RECVPACKSTATE.IdleState;
                }
                break;

            case RECVPACKSTATE.DataPacketState:                                 //接收数据
                if (DataCnt < 19)
                {
                    RecvDataField[DataCnt] = RecvByte;
                    DataCnt++;
                    CurrentRecvState = RECVPACKSTATE.DataPacketState;
                }
                else
                {
                    RecvDataField[DataCnt] = RecvByte;
                    //若校验通过, 则解析数据
                    if (AppUtil.GetChecksum(RecvDataField, 0, 19) == RecvDataField[19])
                    {
                        byte DIRECT = (byte)(RecvDataField[0] >> 4);                                    //指令方向, 先过滤一些数据
                        if (DIRECT == 0x02 || DIRECT == 0x04 || DIRECT == 0x08)                         //2:(终端-主机), 4:(中继-主机), 8:(非本组设备之间的通信)
                        {
                            SerialRecvMsg recvMsg = new SerialRecvMsg();
                            Array.Copy(RecvDataField, 0, recvMsg.PacketData.DataBytes, 2, RecvDataField.Length);
                            recvMsg.PacketData.updateDataBytesToField();                                        //将接收到的字节更新到数据包的各个字段(如dir, path, cmd等)
                            PacketHandler(recvMsg);
                        }
                    }

                    CurrentRecvState = RECVPACKSTATE.IdleState;
                }
                break;

            default:
                CurrentRecvState = RECVPACKSTATE.IdleState;
                break;
            }
        }
示例#3
0
        //从接收队列中取走消息, 返回null代表无消息
        public SerialRecvMsg RecvQueue_Dequeue()
        {
            SerialRecvMsg recvMsg = null;

            if (serialRecvQueue.Count > 0)
            {
                lock (this.serialRecvQueue) { recvMsg = serialRecvQueue.Dequeue(); }
            }
            return(recvMsg);
        }
示例#4
0
 //向接收队列中投递消息
 public bool RecvQueue_Enqueue(SerialRecvMsg recvMsg)
 {
     lock (this.serialRecvQueue) { serialRecvQueue.Enqueue(recvMsg); }
     RecvQueueWaitHandle.Set();
     return(true);
 }
示例#5
0
        //从重发字典中取出消息, 判断是否超时, 然后投入"底层发送队列"
        private void SerialResend()
        {
            DateTime      dtNow;
            List <string> list = new List <string>();

            while (true)
            {
                if (serialPortIsOpen && (resendDic.Count > 0))
                {
                    lock (resendDic)
                    {
                        dtNow = DateTime.Now;
                        list.Clear();
                        //遍历重发字典, 查找超时的消息, 并进行响应操作
                        foreach (var sendMsg in resendDic)
                        {
                            if ((int)((dtNow - sendMsg.Value.SendTime).TotalMilliseconds) > sendMsg.Value.SendWaitTime) //若超时
                            {
                                list.Add(sendMsg.Key);                                                                  //将超时消息的键存入list中, 为后面的移除工作做准备
                                if (sendMsg.Value.SendNumMax > 0)                                                       //若重发次数大于0, 则继续投入发送队列中
                                {
                                    this.SendQueue_Enqueue(sendMsg.Value);
                                }
                                else                                                                                                    //若不能再重发了, 则投入接收处理的队列中
                                {
                                    SerialRecvMsg recvMsg = new SerialRecvMsg();
                                    recvMsg.PacketData = sendMsg.Value.PacketData;
                                    //将发送命令变为响应
                                    if (recvMsg.PacketData.Cmd != 0x09)
                                    {
                                        recvMsg.PacketData.Cmd += 1;
                                    }
                                    else
                                    {
                                        recvMsg.PacketData.Cmd = 0x10;
                                    }
                                    recvMsg.IsFromExtern = false;                       //内部消息(由于多次重发还是未收到响应导致)
                                    this.RecvQueue_Enqueue(recvMsg);                    //投入接收消息队列中
                                                                        #if DEBUG       //将发送消息投入调试队列中
                                    if (SerialComDebug.isPauseDebug == false)           //若当前不是暂停状态
                                    {
                                        recvMsg.RecvTime = DateTime.Now;                //记录时间
                                        this.DebugQueue_Enqueue(recvMsg);
                                    }
                                                                        #endif
                                }
                            }
                        }
                        //将超时消息从重发字典中移除
                        if (list.Count > 0)
                        {
                            foreach (string key in list)
                            {
                                resendDic.Remove(key);
                            }
                        }
                    }
                }
                Thread.Sleep(5);
            }
        }