void DecryptStream(byte[] encrypted) { Stream s; if (decryptor != null) { MemoryStream msDecrypt = new MemoryStream(encrypted); s = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read); } else { s = new MemoryStream(encrypted); } BinaryReader binReader = new BinaryReader(s); byte[] opcode = binReader.ReadBytes(2); if (BitConverter.IsLittleEndian) { Array.Reverse(opcode); } Int16 id = BitConverter.ToInt16(opcode, 0); byte[] data = binReader.ReadBytes(encrypted.GetLength(0) - 2); //Debug.Log("receive NetMsgId : " + id); NetProto.Api.ENetMsgId msgId = (NetProto.Api.ENetMsgId)id; // 将数据压入到消息队列中. PushMsg(msgId, data); s.Close(); }
void PushMsg(NetProto.Api.ENetMsgId id, byte[] data) { lock (msgQueue.SyncRoot) { Msg msg = new Msg(); msg.id = id; msg.data = data; msgQueue.Enqueue(msg); } }
/** * 发送数据包 * * 发送的数据格式: * ----------2---------------4--------------------2--------------data--------------------- * -------字节长度----------序列id----------------消息类型---------消息体(model)-------------- */ public void Send(NetProto.Api.ENetMsgId msgId, IMessage model) { byte[] data = SerializeManager.Serialize(model); // 序列化对象 Int16 id = (Int16)msgId; UInt16 payloadSize = 6; // sizeof(seqid) + sizeof(msgid) //payloadSize += (UInt16)data.Length; payloadSize += (UInt16)data.Length; // payload byte[] payload = new byte[payloadSize]; // seqid Byte[] _seqid = BitConverter.GetBytes(seqId); if (BitConverter.IsLittleEndian) { Array.Reverse(_seqid); } _seqid.CopyTo(payload, 0); // opcode Byte[] _opcode = BitConverter.GetBytes(id); if (BitConverter.IsLittleEndian) { Array.Reverse(_opcode); } _opcode.CopyTo(payload, 4); // data if (data != null) { data.CopyTo(payload, 6); } // try encrypt byte[] encrypted = EncryptStream(payload); // =>pack byte[] buffer = new byte[2 + payloadSize]; // sizeof(header) + payloadSize // =>header Byte[] _header = BitConverter.GetBytes(payloadSize); if (BitConverter.IsLittleEndian) { Array.Reverse(_header); } _header.CopyTo(buffer, 0); // =>payload encrypted.CopyTo(buffer, 2); sendDone.Reset(); // 发出一条消息后重置心跳时间 heartbeatCount = 0; try { //Debug.Log("msgId---------------send : " + msgId); socket.BeginSend(buffer, 0, buffer.Length, 0, new AsyncCallback(SendCallback), socket); sendDone.WaitOne(); } catch (Exception e) { isConnected = false; // 如果socket已经断了,报这个异常 // System.Net.Sockets.SocketException: The socket is not connected Debug.Log(e.ToString()); startReConnect(); } }
// 处理消息 public bool Invoke(NetProto.Api.ENetMsgId id, byte[] data) { return(dispatcher.InvokeHandler(id, data)); }
// 发送数据包 public void Send(NetProto.Api.ENetMsgId msgId, NetProto.Proto.NetBase packet) { Int16 id = (Int16)msgId; seqId++; UInt16 payloadSize = 6; // sizeof(seqid) + sizeof(msgid) byte[] data = null; if (packet != null) { NetProto.Proto.ByteArray ba = new NetProto.Proto.ByteArray(); packet.Pack(ba); data = ba.Data(); ba.Dispose(); if (data.Length > UInt16.MaxValue - 6) { Debug.LogError(data.Length + " > UInt16.MaxValue-6"); return; } payloadSize += (UInt16)data.Length; } if (_beforeSendHook != null) { _beforeSendHook(msgId, data); } // payload byte[] payload = new byte[payloadSize]; // seqid Byte[] _seqid = BitConverter.GetBytes(seqId); if (BitConverter.IsLittleEndian) { Array.Reverse(_seqid); } _seqid.CopyTo(payload, 0); // opcode Byte[] _opcode = BitConverter.GetBytes(id); if (BitConverter.IsLittleEndian) { Array.Reverse(_opcode); } _opcode.CopyTo(payload, 4); // data if (data != null) { data.CopyTo(payload, 6); } // try encrypt byte[] encrypted = EncryptStream(payload); // =>pack byte[] buffer = new byte[2 + payloadSize]; // sizeof(header) + payloadSize // =>header Byte[] _header = BitConverter.GetBytes(payloadSize); if (BitConverter.IsLittleEndian) { Array.Reverse(_header); } _header.CopyTo(buffer, 0); // =>payload encrypted.CopyTo(buffer, 2); sendDone.Reset(); try { socket.BeginSend(buffer, 0, buffer.Length, 0, new AsyncCallback(SendCallback), socket); } catch (Exception e) { // 如果socket已经断了,报这个异常 // System.Net.Sockets.SocketException: The socket is not connected Debug.Log(e.ToString()); } }
void AfterRecvHook(NetProto.Api.ENetMsgId msgId) { Debug.Log("RECV " + msgId); }
void BeforeSendHook(NetProto.Api.ENetMsgId msgId, byte[] data) { Debug.Log("SEND " + msgId); // 发出一条消息后重置心跳时间 heartbeatCount = 0; }