/// <summary> /// 响应串口层上传的数据 /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void ReceiveData(object sender, DataTransmissionEventArgs args) { AsyncSocketUserToken socket = args.Token; if (socket == null) { return; } long ip = ControllerManager.GetLongIPFromSocket(socket); SocketBuffer buffer = null; lock (m_HashReceivedBuffer) { if (m_HashReceivedBuffer.ContainsKey(ip)) { buffer = (SocketBuffer)m_HashReceivedBuffer[ip]; } else { buffer = new SocketBuffer(); m_HashReceivedBuffer.Add(ip, buffer); } buffer.RemoteSock = socket; //lxm 20161013修改,传入的字节流要进行一次转换,将字符字节两两合成一个16进制数据,比如:'F'和'5' 合成0xF5 buffer.ReceivedCharBuffer.AddRange(args.EventData); args.EventData.Clear(); buffer.IsReady = Char2Hex(buffer); if (buffer.IsReady) { m_SemReceiveCommand.Release(1); } } }
/// <summary> /// 解析数据包,生成Command对象,并调用HandleReceivedCommand方法 /// </summary> private void AnalysizeProc() { //int iHeadReadCount = 0; while (m_Keeping && m_SemReceiveCommand != null) { //如果等待超时,继续下一次等待 if (!m_SemReceiveCommand.WaitOne(m_Timeout)) { continue; } SocketBuffer buffer = FindSocketBuffer(); if (buffer == null) { Logger.Instance().Error("AnalysizeProc() FindSocketBuffer错误,未能找到相关SocketBuffer"); continue; } if (buffer.ReceivedBuffer.Count <= 0) { continue; } //读头部固定7字节 buffer.HeadReadCount = CatchStartMessage(buffer); if (buffer.HeadReadCount < HEADLENGTH) { continue; } if (CatchPayloadDataAndChecksum(buffer) < 0) { continue; } else { //解析完成,所有数据清零 BaseCommand cmd = CreateCommand(buffer.CommandBuffer); buffer.HeadReadCount = 0; if (null != ShowBytesOnUI) { ShowBytesOnUI(this, new SendOrReceiveBytesArgs(buffer.CommandBuffer, false)); } buffer.CommandBuffer.Clear(); if (cmd == null) { continue; } cmd.RemoteSocket = buffer.RemoteSock; //每次有新的命令到来,检查下控制器,是否有SocketToken==null的情况,如果有,则更新 Controller controller = ControllerManager.Instance().Get(buffer.RemoteSock); if (controller != null && controller.SocketToken == null) { controller.SocketToken = buffer.RemoteSock; } HandleReceivedCommand(ControllerManager.GetLongIPFromSocket(buffer.RemoteSock), cmd); } } }
/// <summary> /// 捕捉命令头7个字节,目前只能做到部分容错 /// </summary> /// <returns></returns> private int CatchStartMessage(SocketBuffer buffer) { int iCount = 0; lock (buffer) { //读头部7个固定字节(读到Payload length) iCount = buffer.ReceivedBuffer.Count; if (iCount < HEADLENGTH) { Logger.Instance().ErrorFormat("CatchStartMessage() Error,数据头长度小于7 buffer.ReceivedBuffer.Count={0}", iCount); return(-1); } byte [] temp = new byte[HEADLENGTH]; buffer.ReceivedBuffer.CopyTo(0, temp, 0, HEADLENGTH); buffer.CommandBuffer.Clear(); buffer.CommandBuffer.AddRange(temp); buffer.ReceivedBuffer.RemoveRange(0, HEADLENGTH); //读完数据后,立即移走 } return(buffer.CommandBuffer.Count); }
private SocketBuffer FindSocketBuffer() { SocketBuffer buffer = null; lock (m_HashReceivedBuffer) { foreach (DictionaryEntry de in m_HashReceivedBuffer) { if (((SocketBuffer)de.Value).IsReady) { buffer = (SocketBuffer)(de.Value); buffer.IsReady = false; break; } else { continue; } } } return(buffer); }
/// <summary> /// 读数据体及Checksum /// </summary> /// <returns></returns> private int CatchPayloadDataAndChecksum(SocketBuffer buffer) { if (buffer.CommandBuffer.Count < 5) //这里应该报错。因为部首5字节不完整 { Logger.Instance().Error("CatchPayloadDataAndChecksum Error! buffer.CommandBuffer.Count<6"); return(-1); } lock (buffer.ReceivedBuffer) { byte payloadLength = buffer.CommandBuffer[3]; int iCount = buffer.ReceivedBuffer.Count; if (iCount < payloadLength + 4) { //数据体长度+Checksum(4字节),缓存中数量不够,重新等下一次信号量 Logger.Instance().Error("CatchPayloadDataAndChecksum Error! buffer.ReceivedBuffer.Count < payloadLength + 4"); return(-2); } buffer.CommandBuffer.AddRange(buffer.ReceivedBuffer.GetRange(0, payloadLength + 4)); //temp.Clear(); buffer.ReceivedBuffer.RemoveRange(0, payloadLength + 4); //读完数据后,立即移走 } return(0); }
/// <summary> /// 读数据体及Checksum /// </summary> /// <returns></returns> private int CatchPayloadDataAndChecksum(SocketBuffer buffer) { if (buffer.CommandBuffer.Count < HEADLENGTH) //这里应该报错。因为部首7字节不完整 { Logger.Instance().Error("CatchPayloadDataAndChecksum Error! buffer.CommandBuffer.Count<7"); return(-1); } lock (buffer.ReceivedBuffer) { ushort payloadLength = (ushort)(buffer.CommandBuffer[4] << 8); payloadLength += (ushort)buffer.CommandBuffer[3]; int iCount = buffer.ReceivedBuffer.Count; if (iCount < payloadLength + 4) { //数据体长度+Checksum(4字节),缓存中数量不够,重新等下一次信号量 Logger.Instance().Error("CatchPayloadDataAndChecksum Error! buffer.ReceivedBuffer.Count < payloadLength + 4"); return(-2); } buffer.CommandBuffer.AddRange(buffer.ReceivedBuffer.GetRange(0, payloadLength + 4)); buffer.ReceivedBuffer.RemoveRange(0, payloadLength + 4); //读完数据后,立即移走 } return(0); }
/// <summary> /// 接收到的字符转成 /// </summary> /// <param name="buffer"></param> /// <returns></returns> private bool Char2Hex(SocketBuffer buffer) { List <byte> charBuffer = buffer.ReceivedCharBuffer; int headIndex = charBuffer.IndexOf(0x02); int tailIndex = charBuffer.IndexOf(0x03); long ip = ControllerManager.GetLongIPFromSocket(buffer.RemoteSock); string szIP = ControllerManager.Long2IP(ip); if (headIndex < 0) { //如果连包头都不存在,那么整个包都删除, string str = BufferToString(charBuffer); Logger.Instance().ErrorFormat("Char2Hex()->找不到包头字节0x02, charBuffer长度为{0},IP={1},缓冲区数据={2}, 清空!", charBuffer.Count, szIP, str); buffer.ReceivedBuffer.Clear(); return(false); } else { if (tailIndex < 0) { //如果包尾不存在,继续 Logger.Instance().ErrorFormat("Char2Hex()->找不到包尾字节0x03,此包不完整,等待下一次数据到来,charBuffer长度为{0}", charBuffer.Count); return(false); } } //0x02和0x03之间的数据必须是偶数个的 if (tailIndex - headIndex < 10 || (tailIndex - headIndex - 1) % 2 != 0) { charBuffer.RemoveRange(headIndex, tailIndex - headIndex + 1); Logger.Instance().ErrorFormat("Char2Hex()->包头与包尾之间字节数不为偶数或数量小于10,从缓冲区中移动这段数据,并保留余下数据,headIndex={0},tailIndex={1}", headIndex, tailIndex); return(false); } byte[] temp = new byte[tailIndex - headIndex - 1]; charBuffer.CopyTo(headIndex + 1, temp, 0, temp.Length); charBuffer.RemoveRange(headIndex, tailIndex - headIndex + 1); int length = temp.Length; int iLoop = 0; byte byteHigh = 0x00; byte byteLow = 0x00; while (iLoop + 1 < length) { if (temp[iLoop] >= 0x30 && temp[iLoop] <= 0x39) { byteHigh = (byte)((temp[iLoop] - 0x30) << 4); } else if (temp[iLoop] >= 0x41 && temp[iLoop] <= 0x46) { byteHigh = (byte)((temp[iLoop] - 0x37) << 4); } else if (temp[iLoop] >= 0x61 && temp[iLoop] <= 0x66) { byteHigh = (byte)((temp[iLoop] - 0x57) << 4); } else { Logger.Instance().ErrorFormat("Char2Hex 错误,出现0~9,A~F以外的字符 temp[iLoop]={0}, iLoop={1}", temp[iLoop], iLoop); buffer.ReceivedBuffer.Clear(); return(false); } if (temp[iLoop + 1] >= 0x30 && temp[iLoop + 1] <= 0x39) { byteLow = (byte)(temp[iLoop + 1] - 0x30); } else if (temp[iLoop + 1] >= 0x41 && temp[iLoop + 1] <= 0x46) { byteLow = (byte)(temp[iLoop + 1] - 0x37); } else if (temp[iLoop + 1] >= 0x61 && temp[iLoop + 1] <= 0x66) { byteLow = (byte)(temp[iLoop + 1] - 0x57); } else { Logger.Instance().ErrorFormat("Char2Hex 错误,出现0~9,A~F以外的字符 temp[iLoop]={0}, iLoop={1}", temp[iLoop], iLoop); buffer.ReceivedBuffer.Clear(); return(false); } byteHigh &= 0xF0; byteLow &= 0x0F; buffer.ReceivedBuffer.Add((byte)(byteHigh + byteLow)); iLoop = iLoop + 2; } Logger.Instance().InfoFormat("IP={0}, Char2Hex() Converted Char bytes={1}", szIP, BufferToString(temp)); return(true); }