/// <summary> /// 连接回调 /// </summary> /// <param name="ar">Ar.</param> public void ConnectCallback(IAsyncResult ar) { // 从state对象获取socket. Socket client = (Socket)ar.AsyncState; bool result = true; try { ClientNetwork._bLoginOut = false; client.EndConnect(ar); // 完成连接. Utils.LogSys.Log("连接成功!"); result = true; Socket handler = client; recieveState = new MsgStream(); if (isDisposed) { return; } recieveState.workSocket = handler; if (readThreadObj != null) { readThreadObj.toStop = true;//让该线程自然结束 } readThreadObj = new ClientSocketReadThread(); readThreadObj.recieveState = recieveState; readThread = new Thread(new ThreadStart(readThreadObj.BeginListen)); //创建一个新的线程专门用于处理监听 readThread.Start(); } catch (SocketException e) { // 连接失败 // TODO: 展示连接失败 Utils.LogSys.Log("连接失败!" + e.Message); result = false; } if (isDisposed) { return; } EventMultiArgs args = new EventMultiArgs(); args.AddArg("result", result); EventSystem.CallEvent(EventID.SOKECT_CONNECT_RESULT, args); }
//接收到消息 public void ReceiveProtoMsg(MsgStream state, int bytesRead) { clientProtoMsg.ReceiveProtoMsg(state, bytesRead); }
/// <summary> /// 消息解释 /// 消息结构:4Byte的消息长度(含前8Byte)+ 4Byte的消息ID + 内容 /// </summary> /// <param name="state">State.</param> /// <param name="bytesRead">Bytes read.</param> public void ReceiveProtoMsg(MsgStream state, int bytesRead) { if (isDisposed) { state.stream = new MemoryStream(); return; } if (state.stream.Length > 0) { // state.stream = new MemoryStream(); // } // else // { // There might be more data, so store the data received so far. // 将新接收的数据写入stream尾(消息可能被分包,组好后才能解释) state.stream.Position = state.stream.Length; } state.stream.Write(state.buffer, 0, bytesRead); //Utils.LogSys.Log("ReceiveProtoMsg:----------------------->" + state.stream.Length); try{ // Check for end-of-file tag. If it is not there, read // more data. if (state.stream.Length >= 10) { state.stream.Position = 0; uint sumLen = ReadLong(state.stream); long leftLength = state.stream.Length; while (leftLength - 4 >= sumLen) //至少有一个完整的消息时才能解释 { float kb_size = (float)sumLen / 1024f; totalMsgSize += (double)kb_size; // All the data has been read from the // client. Display it on the console. uint dlSn = ReadLong(state.stream); if (dlSn == 226) { int test = 1; } if (dlSn == 0 || ServerDlsn == dlSn - 1) { // 正常 if (dlSn != 0) { ServerDlsn = dlSn; } int iProtoType = ReadWord(state.stream); ProtoID protoType = (ProtoID)iProtoType; //state.stream.Position = state.stream.Position + 8; if (state.stream.Length < sumLen - 6 + state.stream.Position) { Utils.LogSys.LogWarning("Receive Msg Too Less: " + iProtoType); Utils.LogSys.LogWarning("Receive Msg Too Less: count: " + sumLen); Utils.LogSys.LogWarning("Receive Msg Too Less: Position: " + state.stream.Position); Utils.LogSys.LogWarning("Receive Msg Too Less: Length: " + state.stream.Length); } MemoryStream protoStream = new MemoryStream(state.stream.ToArray(), (int)state.stream.Position, (int)sumLen - 6); protoStream.Position = 0; if (!Enum.IsDefined(typeof(ProtoID), iProtoType)) { Utils.LogSys.LogWarning("Receive Msg Not Defined: " + iProtoType); MsgCallManager.addMsgObj(protoType, protoStream); } else { #if UNITY_EDITOR Utils.LogSys.Log("Receive Msg : " + protoType + "(size:" + sumLen + ")"); #endif if (ProtoEncryptList.protoEncryptList.Contains(protoType)) { byte[] bs = EncryptionUtils.DecryptXor(protoStream, (int)(_encryptKey[0] + dlSn) % 255); protoStream.Dispose(); protoStream = new MemoryStream(bs, 0, (int)sumLen - 6); } object protoMsg = null; try{ protoMsg = ProtoSerializer.ParseFrom(protoType, protoStream); } catch (Exception e) { Utils.LogSys.LogError(protoType); Debug.LogException(e); } if (protoType == ProtoID.SC_LOGIN_REPLY) { _reconnectKey = (protoMsg as sc_login_reply).reconnect_key; _encryptKey = (protoMsg as sc_login_reply).proto_key; } #if UNITY_EDITOR if (protoType != ProtoID.SC_COMMON_HEARTBEAT_REPLY) { Utils.LogSys.Log("Got " + protoType + " proto Len:" + sumLen + ". dlSn: " + dlSn); } #endif protoStream.Seek(0, SeekOrigin.Begin); MsgCallManager.addMsgObj(protoType, protoStream); } // protoStream.Dispose(); } else if (ServerDlsn >= dlSn) { // 过期 ProtoID protoType = (ProtoID)ReadWord(state.stream); #if UNITY_EDITOR Utils.LogSys.LogWarning("收到过期包:" + dlSn + "(protoID:" + protoType.ToString() + "),不再处理,当前已处理的最新包编号是:" + ServerDlsn); #endif } else { // 丢包 ProtoID protoType = (ProtoID)ReadWord(state.stream); #if UNITY_EDITOR Utils.LogSys.LogError("丢失包:(编号" + (ServerDlsn + 1) + "--" + (dlSn - 1) + ") 这次到达的是protoID:" + protoType + " ,已重新请求"); #endif EventSystem.CallEvent(EventID.SERVER_MSG_MISSING, null); } state.stream.Position = state.stream.Position + sumLen - 6; leftLength = state.stream.Length - state.stream.Position; if (leftLength > 0) { bool hasHoleMsg = true; //字节流中是否还有完整的消息 if (leftLength < 10) { hasHoleMsg = false; } else { sumLen = ReadLong(state.stream); state.stream.Position = state.stream.Position - 4; if (sumLen > leftLength - 4) { hasHoleMsg = false; } } //1.未解释完,将剩余的字符流存下来 if (!hasHoleMsg) { MemoryStream newStream = new MemoryStream(); newStream.Write(state.stream.ToArray(), (int)state.stream.Position, (int)leftLength); state.stream.Dispose(); state.stream = newStream; state.stream.Position = 0; } //2.解释完成,继续解释字符流中的下一个消息 else { state.stream.Position = state.stream.Position + 4; } } else { //3.解释完成,new一个空字符流下一个消息 state.stream.Dispose(); state.stream = new MemoryStream(); break; } } } } catch (Exception e) { Debug.LogException(e); } }