/// <summary> /// 接收数据处理,根据信息解析协议,根据协议内容处理消息再下发到客户端 /// </summary> /// <param name="clientSocket"></param> void OnReceiveData(ClientSocket clientSocket) { ByteArray readbuff = clientSocket.ReadBuff; byte[] bytes = readbuff.Bytes; int bodyLength = BitConverter.ToInt32(bytes, readbuff.ReadIdx); //判断接收到的信息长度是否小于包体长度+包体头长度,如果小于,代表我们的信息不全,大于代表信息全了(有可能有粘包存在) if (readbuff.Length < bodyLength + 4) { return; } //解析协议名 ProtocolEnum proto = MsgBase.DecodeName(readbuff.Bytes); if (proto == ProtocolEnum.None) { Debug.LogError("OnReceiveData MsgBase.DecodeName fail"); CloseClient(clientSocket); return; } readbuff.ReadIdx += 4; //解析协议体 int bodyCount = bodyLength - readbuff.Bytes[4] - 2; MsgBase msgBase = MsgBase.Decode(proto, readbuff.Bytes, bodyCount); if (msgBase == null) { Debug.LogError("{0}协议内容解析错误:" + proto.ToString()); CloseClient(clientSocket); return; } //通过反射分发消息 MethodInfo mi = typeof(MsgHandler).GetMethod(proto.ToString()); object[] o = { clientSocket, msgBase }; if (mi != null) { mi.Invoke(null, o); } else { Debug.LogError("OnReceiveData Invoke fail:" + proto.ToString()); } readbuff.ReadIdx += bodyLength; readbuff.CheckAndMoveBytes(); //继续读取消息 处理黏包 if (readbuff.Length > 4) { OnReceiveData(clientSocket); } }
/// <summary> /// 协议解密,以及反序列化 /// </summary> /// <param name="protocol"></param> /// <param name="bytes"></param> /// <param name="offset"></param> /// <param name="count"></param> /// <returns></returns> public static MessageBase Decode(ProtocolEnum protocol, byte[] bytes, int offset, int count) { if (count <= 0) { Debug.LogError("协议解密出错,数据长度为0"); return(null); } string secret = string.IsNullOrEmpty(NetManager.Instance.Secretkey) ? NetManager.Instance.PublicKey : NetManager.Instance.Secretkey; try { byte[] newBytes = new byte[count]; Array.Copy(bytes, offset, newBytes, 0, count); //// 解密 newBytes = AES.AESDecrypt(newBytes, secret); using (var memory = new MemoryStream(newBytes, 0, newBytes.Length)) { // 这里要求对应的协议类型类,要与协议枚举的名字一一对应 Type t = System.Type.GetType(protocol.ToString()); return((MessageBase)Serializer.NonGeneric.Deserialize(t, memory)); } } catch (Exception ex) { Debug.LogError("协议解密出错 :" + ex); return(null); } }
/// <summary> /// 协议解密,以及反序列化 /// </summary> /// <param name="protocol"></param> /// <param name="bytes"></param> /// <param name="offset"></param> /// <param name="count"></param> /// <returns></returns> public static MessageBase Decode(ProtocolEnum protocol, byte[] bytes, int offset, int count) { if (count <= 0) { Debug.LogError("协议解密出错,数据长度为0"); return(null); } try { byte[] newBytes = new byte[count]; Array.Copy(bytes, offset, newBytes, 0, count); string secret = ServerSocket.SecretKey; // 请求加密使用的是公钥加密 if (protocol == ProtocolEnum.MessageSecret) { secret = ServerSocket.PublicKey; } // 解密 newBytes = AES.AESDecrypt(newBytes, secret); using (var memory = new MemoryStream(newBytes, 0, newBytes.Length)) { // 这里要求对应的协议类型类,要与协议枚举的名字一一对应(这里的类最好不要有命名空间包裹,若有,可能识别不到) Type t = System.Type.GetType(protocol.ToString()); return((MessageBase)Serializer.NonGeneric.Deserialize(t, memory)); } } catch (Exception ex) { Debug.LogError("协议解密出错 :" + ex); return(null); } }
public static MsgBase Decode(ProtocolEnum protocol, byte[] bytes, int offset, int count) { if (count <= 0) { Debug.LogError("协议解密出错,数据长度为0"); return(null); } try { byte[] newBytes = new byte[count]; Array.Copy(bytes, offset, newBytes, 0, count); string secret = ServerSocket.Secretkey; if (protocol == ProtocolEnum.MsgSecret) { secret = ServerSocket.PublicKey; } newBytes = AES.AESDecrypt(newBytes, secret); using (var memory = new MemoryStream(newBytes, 0, newBytes.Length)) { Type t = System.Type.GetType(protocol.ToString()); return((MsgBase)Serializer.NonGeneric.Deserialize(t, memory)); } } catch (Exception ex) { Debug.LogError("协议解密出错:" + ex); return(null); } }
/// <summary> /// 接收信息,并解析 /// </summary> /// <param name="cleint"></param> void OnReceiveData(ClientSocket clintSocket) { ByteArray readBuff = clintSocket.ReadBuff; // 基本消息长度判断(一个协议头为 4) if (readBuff.Length <= 4 || readBuff.ReadIndex < 0) { Debug.Log("数据小于 4"); return; } int readIndex = readBuff.ReadIndex; byte[] bytes = readBuff.Bytes; //解析协议头,获得中的长度 int bodyLength = BitConverter.ToInt32(bytes, readIndex); // (分包处理)判断接收消息长度是否小于包体长度+包头长度,如果小于,代表接收到的消息不全(返回,不做处理,等下一次全了在处理),大于则代表消息全了(也有可能有粘包存在) if (readBuff.Length < bodyLength + 4) { Debug.Log("数据不完整"); return; } // 移动到消息体位置 readBuff.ReadIndex += 4; // 解析协议名称 int nameCount = 0; ProtocolEnum protocol = ProtocolEnum.None; try { protocol = MessageBase.DecodeName(readBuff.Bytes, readBuff.ReadIndex, out nameCount); } catch (Exception ex) { Debug.LogError("解析协议名称 Error :" + ex); CloseClient(clintSocket); return; } // 协议名称为空 if (protocol == ProtocolEnum.None) { Debug.LogError("OnReceiveData MessageBase.DecodeName() Fail :"); CloseClient(clintSocket); return; } // 解析协议内容 readBuff.ReadIndex += nameCount; int bodyCount = bodyLength - nameCount; MessageBase messageBase = null; try { messageBase = MessageBase.Decode(protocol, readBuff.Bytes, readBuff.ReadIndex, bodyCount); if (messageBase == null) { Debug.LogError("{0} 解析协议内容 Error ", protocol.ToString()); CloseClient(clintSocket); return; } } catch (Exception ex) { Debug.LogError("解析协议内容 Error :" + ex); CloseClient(clintSocket); return; } // 移动读取位置,并且继续判断移动数据 readBuff.ReadIndex += bodyCount; readBuff.CheckAndMoveBytes(); //通过反射,分发消息(解析完数据,对应的处理) MethodInfo methodInfo = typeof(MessageHandler).GetMethod(protocol.ToString()); object[] o = { clintSocket, messageBase }; if (methodInfo != null) { methodInfo.Invoke(null, o); } else { Debug.LogError("OnReceiveData Invok Fail:" + protocol.ToString()); } // 继续读取消息(粘包现象处理) if (readBuff.Length > 4) { OnReceiveData(clintSocket); } }