客户端关闭连接
在NetManager
中添加CloseConnection
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| void ReceiveCallback(IAsyncResult ar) { try { Socket socket = (Socket)ar.AsyncState; int count = socket.EndReceive(ar); if(count <= 0) { CloseConnection(); return; } }
public void CloseConnection(bool normal = true) { if(m_Socket == null || m_IsConnecting) return;
SecretKey = ""; m_Socket.Close(); FirstEvent(NetEvent.Close,normal.ToString()); Debug.Log("CloseSocket"); }
|
修改MsgBase
的Encode
方法和Decode
方法,在客户端中,不需要通过判断消息类型来确定公钥私钥,所以我们删除部分代码。并添加上判断是否持有私钥的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| public static byte[] Encode(MsgBase msg) { string secret; if(string.IsNullOrEmpty(NetManager.Instance.SecretKey)) { secret = NetManager.Instance.PublicKey; } else { secret = NetManager.Instance.SecretKey; } using(MemoryStream ms = new MemoryStream()) { Serializer.Serialize(ms, msg); byte[] bytes = ms.ToArray(); bytes = AES.AESEncrypt(bytes, secret); return bytes; } } public static MsgBase? Decode(ProtocolEnum protocol,byte[] bytes,int offset,int count) { if (count <= 0) { Debug.LogError("协议解密出错,数据长度为0"); return null; } string secret; if (string.IsNullOrEmpty(NetManager.Instance.SecretKey)) { secret = NetManager.Instance.PublicKey; } else { secret = NetManager.Instance.SecretKey; } try { byte[] newbytes = new byte[count]; Array.Copy(bytes, offset, newbytes, 0, count); newbytes = AES.AESDecrypt(newbytes, secret); using (MemoryStream ms = new MemoryStream(newbytes,0,newbytes.Length)) { } } }
|
客户端解析数据
客户端在回调里解析数据,基本流程和服务端差不多,由于客户端回调是在多线程里面调用的,所以解析出来的数据需要先缓存再解析。
在NetManager
里面添加m_MsgList
和m_MsgCount
,并在初始化时创建好。注意m_MsgCount
不计录心跳包的消息,所以消息列表的长度不是m_MsgList
的Count,一开始所有的消息都会让m_MsgCount + 1
,但客户端分发消息时一旦发现是心跳包消息,会让m_MsgCount - 1
1 2 3 4 5 6 7 8 9 10
| private List<MsgBase> m_MsgList;
private int m_MsgCount; void InitState() { m_MsgList = new List<MsgBase>(); m_MsgCount = 0; }
|
修改NetManager
里面的OnReceiveData
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
void OnReceiveData() { if(m_ReadBuff.Length <=4 || m_ReadBuff.ReadIdx<0) return; int readIdx = m_ReadBuff.ReadIdx; byte[] bytes = m_ReadBuff.Bytes; int bodyLength = BitConverter.ToInt32(bytes, readIdx); if(m_ReadBuff.Length < bodyLength + 4) { return; } m_ReadBuff.ReadIdx += 4; int nameCount; ProtocolEnum protocol = MsgBase.DecodeName(m_ReadBuff.Bytes, m_ReadBuff.ReadIdx, out nameCount); if(protocol == ProtocolEnum.None) { Debug.LogError("OnReceiveData MsgBase.DecodeName fail"); CloseConnection(); return; } m_ReadBuff.ReadIdx += nameCount; int bodyCount = bodyLength - nameCount; try { MsgBase msg = MsgBase.Decode(protocol, m_ReadBuff.Bytes, m_ReadBuff.ReadIdx, bodyCount); if (msg == null) { Debug.LogError("解析协议内容出错"); CloseConnection(); return; } m_ReadBuff.ReadIdx += bodyCount; m_ReadBuff.CheckAndMoveBytes(); lock(m_MsgList) { m_MsgList.Add(msg); } m_MsgCount++; if(m_ReadBuff.Length > 4) { OnReceiveData(); } } catch (Exception ex) { Debug.LogError("OnReceiveData MsgBase.Decode fail" + ex); CloseConnection(); }
}
|