/// <summary> /// 接收客户端发来的信息,客户端套接字对象 /// </summary> /// <param name="socketclientpara"></param> static void recv(object socketclientpara) { Socket socketServer = socketclientpara as Socket; while (isOpen) { //创建一个内存缓冲区,其大小为1024*1024字节 即1M byte[] arrServerRecMsg = new byte[1024 * 1024]; //将接收到的信息存入到内存缓冲区,并返回其字节数组的长度 try { int length = socketServer.Receive(arrServerRecMsg); // 这里只是演示用,实际中可以根据头部消息判断是什么类型的消息,然后再反序列化 MemoryStream clientStream = new MemoryStream(arrServerRecMsg); SCPacketHeader header = Serializer.DeserializeWithLengthPrefix <SCPacketHeader>(clientStream, PrefixStyle.Fixed32); Type packetType = typeof(CSHello); CSHello packet = (CSHello)RuntimeTypeModel.Default.DeserializeWithLengthPrefix( clientStream, ReferencePool.Acquire(packetType), packetType, PrefixStyle.Fixed32, 0); Log.Info("收到客户端消息:" + packet.Name); SCHello response = new SCHello(); response.Name = "客户端你好...调皮"; byte[] datas = null; using (MemoryStream memoryStream = new MemoryStream()) { // 因为头部消息有8字节长度,所以先跳过8字节 memoryStream.Position = 8; Serializer.SerializeWithLengthPrefix(memoryStream, response, PrefixStyle.Fixed32); // 头部消息 SCPacketHeader packetHeader = ReferencePool.Acquire <SCPacketHeader>(); packetHeader.Id = response.Id; packetHeader.PacketLength = (int)memoryStream.Length - 8; // 消息内容长度需要减去头部消息长度 memoryStream.Position = 0; Serializer.SerializeWithLengthPrefix(memoryStream, packetHeader, PrefixStyle.Fixed32); ReferencePool.Release(packetHeader); datas = memoryStream.ToArray(); } socketServer.Send(datas); } catch (Exception ex) { clientConnectionItems.Remove(socketServer.RemoteEndPoint.ToString()); Log.Debug("Client Count:" + clientConnectionItems.Count); //提示套接字监听异常 Log.Debug("客户端" + socketServer.RemoteEndPoint + "已经中断连接" + "\r\n" + ex.Message + "\r\n" + ex.StackTrace + "\r\n"); //关闭之前accept出来的和客户端进行通信的套接字 socketServer.Close(); break; } } }
/// <summary> /// **GF程序集内部执行 /// 反序列化消息包头 /// </summary> /// <param name="source"></param> /// <param name="customErrorData"></param> /// <returns></returns> public IPacketHeader DeserializePacketHeader(Stream source, out object customErrorData) { // 注意:此函数并不在主线程调用! customErrorData = null; //方式1:直接用字节读id+packtLen SCPacketHeader header = ReferencePool.Acquire <SCPacketHeader>(); byte[] idData = new byte[4]; byte[] lenData = new byte[4]; source.Position = 0; source.Read(idData, 0, 4); source.Read(lenData, 0, 4); int id = BitConverter.ToInt32(idData, 0); int len = BitConverter.ToInt32(lenData, 0); header.Id = id; header.PacketLength = len; return(header); //方式2:用Proto结构体反序列化包头(暂时没测通) //return Serializer.DeserializeWithLengthPrefix<SCPacketHeader>(source, PrefixStyle.Fixed32); //return (IPacketHeader)RuntimeTypeModel.Default.Deserialize(source, ReferencePool.Acquire<SCPacketHeader>(), typeof(SCPacketHeader)); }
/// <summary> /// **GF程序集内部执行 /// 反序列化消息包 /// </summary> /// <param name="packetHeader"></param> /// <param name="source"></param> /// <param name="customErrorData"></param> /// <returns></returns> public Packet DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData) { // 注意:此函数并不在主线程调用! customErrorData = null; SCPacketHeader packetHeaderImpl = packetHeader as SCPacketHeader; if (packetHeaderImpl == null) { Log.Warning("Packet header is null."); return(null); } Packet packet = null; if (packetHeaderImpl.IsValid()) { Type packetType = GetServerToClientPacketType(packetHeaderImpl.Id); if (packetType != null) { packet = (Packet)RuntimeTypeModel.Default.Deserialize(source, ReferencePool.Acquire(packetType), packetType); } else { Log.Warning("Can't deserialize packet id '{0}'.", packetHeaderImpl.Id); } } else { Log.Warning("Packet header is invalid. Id : {0}", packetHeaderImpl.Id); } ReferencePool.Release(packetHeaderImpl); return(packet); }