public void AsyncRead() { if (!IsOpen()) { return; } _readBuffer.Normalize(); _readBuffer.EnsureFreeSpace(); try { _socket.BeginReceive(_readBuffer.Data(), _readBuffer.Wpos(), _readBuffer.GetRemainingSpace(), SocketFlags.None, out _error, ReceiveDataCallback, null); } catch (Exception ex) { CloseSocket(); if (LogException) { if (NetSettings.Logger != null) { NetSettings.Logger.Warn(ex); } else { Console.WriteLine(ex); } } } }
protected void DeserializePacket(Type packetType, bool compressed, int size, MessageBuffer packetBuffer) { // Invoke the following generic method here to enable AOT // public static T Deserialize<T>(ReadOnlyMemory<byte> buffer, MessagePackSerializerOptions options = null, CancellationToken cancellationToken = default); MethodInfo genericDeserializeMethod; if (!_GenericDeserializeMethods.TryGetValue(packetType, out genericDeserializeMethod)) { genericDeserializeMethod = DeserializeMethod.MakeGenericMethod(packetType); _GenericDeserializeMethods[packetType] = genericDeserializeMethod; } try { var memory = new ReadOnlyMemory <byte>(packetBuffer.Data(), packetBuffer.Rpos(), size); _parameterCache.Value[0] = memory; _parameterCache.Value[1] = compressed ? NetSettings.LZ4CompressOptions : NetSettings.MessagePackOptions; var obj = genericDeserializeMethod.Invoke(null, _parameterCache.Value); if (Session != null) { Session.QueuePacket(obj as ObjectPacket); } } catch { if (LogException) { var message = string.Format("Client {0} sent malformed packet (size: {1}, packetType: {2}).", RemoteAddress, size, packetType); if (NetSettings.Logger != null) { NetSettings.Logger.Warn(message); } else { Console.WriteLine(message); } } if (CloseOnMalformedPacket) { CloseSocket(); return; } else { // Buffer are corrupted, reset! packetBuffer.Reset(); return; } } packetBuffer.ReadCompleted(size); }
public void SendObjectPacket(ObjectPacket packet, bool encrypt, bool compress = false) { // Invoke the following generic method here to enable AOT // public static byte[] Serialize<T>(T value, MessagePackSerializerOptions options = null, CancellationToken cancellationToken = default); MethodInfo genericSerializeMethod; var packetType = packet.GetType(); if (!_GenericSerializeMethods.TryGetValue(packetType, out genericSerializeMethod)) { genericSerializeMethod = SerializeMethod.MakeGenericMethod(packetType); _GenericSerializeMethods[packetType] = genericSerializeMethod; } _parameterCache2.Value[0] = packet; _parameterCache2.Value[1] = compress ? NetSettings.LZ4CompressOptions : NetSettings.MessagePackOptions; var data = genericSerializeMethod.Invoke(null, _parameterCache2.Value) as byte[]; var size = data.Length + HeaderTailSize; var buffer = new MessageBuffer(size + (ServerSocket ? 4 : 2)); if (ServerSocket) { buffer.Write(BitConverter.GetBytes((int)size), 4); } else { buffer.Write(BitConverter.GetBytes((ushort)size), 2); } buffer.Write(BitConverter.GetBytes(packet.PacketId), 4); buffer.Write(BitConverter.GetBytes(compress), 1); buffer.Write(data, data.Length); if (encrypt) { _authCrypt.EncryptSend(buffer.Data(), 0, SendHeaderSize); } SendPacket(buffer); }
protected void AsyncProcessQueue() { if (_closed.Value) { return; } if (_isWritingAsync.Exchange(true)) { return; } MessageBuffer buffer = null; if (!_writeQueue.TryPeek(out buffer)) { _isWritingAsync.Exchange(false); return; } try { _socket.BeginSend(buffer.Data(), buffer.Rpos(), buffer.GetActiveSize(), SocketFlags.None, out _error, SendDataCallback, null); } catch (Exception ex) { CloseSocket(); if (LogException) { if (NetSettings.Logger != null) { NetSettings.Logger.Warn(ex); } else { Console.WriteLine(ex); } } } }
protected override void ReadHandler() { MessageBuffer buffer = GetReadBuffer(); while (buffer.GetActiveSize() > 0) { int size = RecvHeaderSize; if (buffer.GetActiveSize() < size) { break; } // We just received nice new header if (!_NextPacketDecrypted) { _authCrypt.DecryptRecv(buffer.Data(), buffer.Rpos(), size); } _NextPacketDecrypted = false; var addr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer.Data(), buffer.Rpos()); int packetId; bool compressed; if (ServerSocket) { var header = Marshal.PtrToStructure <ClientPacketHeader>(addr); size = header.Size + sizeof(ushort); packetId = header.PacketId; compressed = header.Compressed != 0; } else { var header = Marshal.PtrToStructure <ServerPacketHeader>(addr); size = header.Size + sizeof(int); packetId = header.PacketId; compressed = header.Compressed != 0; } var packetType = ObjectPacket.GetPacketType(packetId); if (packetType == null || size <= 0 || size >= _MaxPacketSize) { if (LogException) { var message = string.Format("Client {0} sent malformed packet (size: {1}, packetId: {2}).", RemoteAddress, size, packetId); if (NetSettings.Logger != null) { NetSettings.Logger.Warn(message); } else { Console.WriteLine(message); } } if (CloseOnMalformedPacket) { CloseSocket(); return; } else { // Buffer are corrupted, reset! buffer.Reset(); continue; } } if (buffer.GetActiveSize() < size) { // NOTE: The header buffer of next upcoming packet is already decrypted in above code. // We must skip _authCrypt.DecryptRecv() for next packet. _NextPacketDecrypted = true; break; } buffer.ReadCompleted(RecvHeaderSize); size -= RecvHeaderSize; DeserializePacket(packetType, compressed, size, buffer); } AsyncRead(); }