private void SerialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { try { var recivemsg = ReadMsgFromPort(); while (recivemsg != null) { if (recivemsg is IBackMsg) { //接收到其他信息就当作时回复 backMsg = recivemsg; resetEvent.Set(); } else { //接收到事件消息冒泡出去 ReciveEvent(recivemsg); } recivemsg = ReadMsgFromPort(); } } catch (Exception ex) { OnIODebug?.Invoke(ex.ToString(), null); } //int Existlen = serialPort.BytesToRead; //if (Existlen >=8) //{ // byte[] bts = new byte[Existlen]; // serialPort.Read(bts, 0, bts.Length); // OnIODebug?.Invoke("丢弃数据:", bts); //} }
/// <summary> /// 回应数据 /// </summary> /// <param name="msg"></param> public void BackMsg(Message msg) { if (msg == null) { return; } lock (this) { try { isbuzy = true; if ((System.DateTime.Now - LastSend).TotalMilliseconds < 6) { System.Threading.Thread.Sleep(6);//如果连续发送需要间隔6毫秒 } if (msg is ITransMsg) { (msg as ITransMsg).TransID = LastReciveTransID; } byte[] data = msg.GetMsgData(); OnIODebug?.Invoke(msg.ToString(), data); backMsg = null; LastSend = System.DateTime.Now; serialPort.Write(data, 0, data.Length); } catch (Exception ex) { throw ex; } finally { isbuzy = false; } } }
/// <summary> /// 发送并等待回应 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="msg"></param> /// <param name="timeout"></param> /// <returns></returns> public T SendAndBackMsg <T>(Message msg, int timeout) where T : Message { lock (this) { try { isbuzy = true; if ((System.DateTime.Now - LastSend).TotalMilliseconds < 6) { System.Threading.Thread.Sleep(6);//如果连续发送需要间隔6毫秒 } if (msg is ITransMsg && !msg.MsgDataPacked) { (msg as ITransMsg).TransID = GetNextTransID(); } byte[] data = msg.GetMsgData(); OnIODebug?.Invoke("发送\r\n" + msg.ToString(), data); backMsg = null; LastSend = System.DateTime.Now; serialPort.Write(data, 0, data.Length); resetEvent.Reset(); if (!resetEvent.WaitOne(timeout)) { throw new Exception("接收数据超时"); } if (!(backMsg is T)) { throw new Exception("回应的数据与预期不一致"); } return(backMsg as T); } catch (Exception ex) { throw ex; } finally { isbuzy = false; } } }
private Message ReadMsgFromPort() { if (serialPort.BytesToRead < 8) { return(null); } byte[] buffer = new byte[40960]; int bufferlength = 0; bufferlength = serialPort.Read(buffer, 0, 8);//读取包头 if (buffer[0] != 0xEF || buffer[1] != 0x37) { byte[] bts = new byte[serialPort.BytesToRead + bufferlength]; Array.Copy(buffer, bts, bufferlength); serialPort.Read(bts, bufferlength, serialPort.BytesToRead); OnIODebug?.Invoke("包头错误", bts); return(null); } int DataLen = (((int)(buffer[6])) << 8) | buffer[7]; int bttoread = serialPort.BytesToRead; int waittimes = 0; while (bttoread < DataLen + 4) //没接收完成 { if (serialPort == null) { break; } if (!serialPort.IsOpen) { break; } if (serialPort.BytesToRead > bttoread) { bttoread = serialPort.BytesToRead; waittimes = 0;//一直有数据收到就继续等 } System.Threading.Thread.Sleep(1); waittimes++; if (waittimes > 5)//6毫秒都没收到数据代表没有了 { break; } } if (bttoread < DataLen + 4) { byte[] bts = new byte[serialPort.BytesToRead + bufferlength]; Array.Copy(buffer, bts, bufferlength); serialPort.Read(bts, bufferlength, serialPort.BytesToRead); OnIODebug?.Invoke("接收到不完整的帧", bts); return(null); } bufferlength += serialPort.Read(buffer, bufferlength, DataLen + 4); if (buffer[DataLen + 10] != 0xFE || buffer[DataLen + 11] != 0x73) { byte[] bts = new byte[bufferlength]; Array.Copy(buffer, bts, bufferlength); OnIODebug?.Invoke("包尾错误", bts); return(null); } byte sum = buffer[0]; byte xor = buffer[0]; for (int i = 1; i < bufferlength - 4; i++) { sum = (byte)(sum + buffer[i]); xor = (byte)(xor ^ buffer[i]); } if (sum != buffer[DataLen + 8] || xor != buffer[DataLen + 9]) { byte[] bts = new byte[bufferlength]; Array.Copy(buffer, bts, bufferlength); OnIODebug?.Invoke("数据校验错误", bts); return(null); } Message recivemsg = Message.ParseFromData(buffer, bufferlength); if (recivemsg == null) { byte[] bts = new byte[bufferlength]; Array.Copy(buffer, bts, bufferlength); OnIODebug("不支持的指令", bts); return(null); } if (OnIODebug != null) { byte[] bts = new byte[bufferlength]; Array.Copy(buffer, bts, bufferlength); OnIODebug("收到" + recivemsg.ToString(), bts); } return(recivemsg); }