/// <summary> /// Synchronously receive a network event, note that this can interfeared with MessageRetrieveCallback if the base socket is already blocking /// </summary> public async Task <NetworkEvent> BlockingReceive() { await BaseSocketReadSem.WaitAsync(); byte[] NewBufferLength = new byte[4]; int BytesReceived; if ((BytesReceived = this.Receive(NewBufferLength, 0, 4, SocketFlags.None, out var ErrorCode)) != 4 || ErrorCode != SocketError.Success) { OnNetworkExceptionOccurred?.Start(this, new OnNetworkExceptionOccurredEventArgs(new Exception($"Invalid ammount of data received from Client! Expected {4} got {BytesReceived} with exception {ErrorCode}"))); return(default(NetworkEvent)); } var BufferLength = BitConverter.ToInt32(NewBufferLength, 0); var Buffer = new byte[BufferLength]; BytesReceived = 0; while (BytesReceived < BufferLength) { var BytesReceiving = this.Receive(Buffer, BytesReceived, BufferLength - BytesReceived, SocketFlags.None, out ErrorCode); if (ErrorCode != SocketError.Success) { OnNetworkExceptionOccurred?.Start(this, new OnNetworkExceptionOccurredEventArgs(new Exception($"Invalid ammount of data received from Client! Expected {BufferLength} got {BytesReceived} with exception {ErrorCode}"))); return(default(NetworkEvent)); } else { BytesReceived += BytesReceiving; } } var Event = SerializationProdiver.Deserialize <NetworkEvent>(Buffer); BaseSocketReadSem.Release(); return(Event); }
/// <summary> /// Synchronously send a network event /// </summary> /// <param name="Event">Event to send</param> public async Task <bool> BlockingSend(NetworkEvent Event) { await BaseSocketWriteSem.WaitAsync(); var Buffer = SerializationProdiver.Serialize(Event); int BytesSent; if ((BytesSent = this.Send(BitConverter.GetBytes(Buffer.Length), 0, 4, SocketFlags.None, out var ErrorCode)) != 4 || ErrorCode != SocketError.Success) { OnNetworkExceptionOccurred?.Start(this, new OnNetworkExceptionOccurredEventArgs(new Exception($"Invalid ammount of data sent to Client! Expected {Buffer.Length} sent {BytesSent} with exception {ErrorCode}"))); return(false); } if ((BytesSent = this.Send(Buffer, 0, Buffer.Length, SocketFlags.None, out ErrorCode)) != Buffer.Length || ErrorCode != SocketError.Success) { OnNetworkExceptionOccurred?.Start(this, new OnNetworkExceptionOccurredEventArgs(new Exception($"Invalid ammount of data sent to Client! Expected {Buffer.Length} sent {BytesSent} with exception {ErrorCode}"))); return(false); } BaseSocketWriteSem.Release(); return(true); }
/// <summary> /// Main message received loop /// </summary> private void MessageRetrieveCallback(IAsyncResult AsyncResult) { if (Stopping) { return; } bool StatusOK; try { if (UseSSL) { StatusOK = SSLStream.EndRead(AsyncResult) != 0; } else { StatusOK = BaseSocket.EndReceive(AsyncResult, out var ErrorCode) != 0 && ErrorCode == SocketError.Success; } } catch { StatusOK = false; } // Check the message state to see if we've been disconnected if (!StatusOK) { OnNetworkClientDisconnected?.Start(this, new OnNetworkClientDisconnectedEventArgs(BaseSocket?.RemoteEndPoint)); this.Close(); return; } // Take our initial first 4 bytes we've received so we know how large the actual message is var BufferLength = BitConverter.ToInt32(NextBufferLength, 0); NextBufferLength = new byte[4]; var Buffer = new byte[BufferLength]; var BytesReceived = 0; while (BytesReceived < BufferLength) { var BytesReceiving = this.Receive(Buffer, BytesReceived, BufferLength - BytesReceived, SocketFlags.None, out var ErrorCode); if (ErrorCode != SocketError.Success) { OnNetworkExceptionOccurred?.Start(this, new OnNetworkExceptionOccurredEventArgs(new Exception($"Invalid ammount of data received from Client! Expected {BufferLength} got {BytesReceived} with exception {ErrorCode}"))); BeginAcceptMessages(); return; } else { BytesReceived += BytesReceiving; } } // Deserialize the decrypted message into a raw object array NetworkEvent DeserializedEvent; try { DeserializedEvent = SerializationProdiver.Deserialize <NetworkEvent>(Buffer); } catch { OnNetworkExceptionOccurred?.Start(this, new OnNetworkExceptionOccurredEventArgs(new Exception($"Corrupted data received!"))); BeginAcceptMessages(); return; } // Notify that we've received a network event OnNetworkMessageReceived?.Start(this, new OnNetworkMessageReceivedEventArgs(DeserializedEvent)); // Loop if (ContinueSubscribing) { BeginAcceptMessages(); } }