/// <summary> /// This callback is for handling the receive of the size header. /// </summary> /// <param name="ar"></param> private void ReceiveSizeCallback(IAsyncResult ar) { try { //Attempt to end the read var read = socket.EndReceive(ar); /*An exception should be thrown on EndReceive if the connection was lost. * However, that is not always the case, so we check if read is zero or less. * Which means disconnection. * If there is a disconnection, we throw an exception*/ if (read <= 0) { throw new SocketException((int)SocketError.ConnectionAborted); } //increment the total data read dataRead += read; //If we didn't receive the full buffer size, something is lagging behind. if (dataRead < SIZE_HEADER) { //Begin receive again BeginReceive(); //If we did receive the full header, then begin reading the payload } else { dataRead = 0; //Get the converted int value for the payload size from the received data dataExpected = BitConverter.ToInt32(buffer, 0); if (dataExpected == NetConstants.PING_REQUEST) { SendPingResponse(); BeginReceive(); return; } else if (dataExpected == NetConstants.PING_RESPONSE) { double ping = ((double)pingWatch.ElapsedTicks / Stopwatch.Frequency) * 1000.0; Ping = ping; BeginReceive(); PingUpdated?.Invoke(this, ping); pingWatch.Restart(); return; } if (dataExpected > ClientOptions.MaxPacketSize) { throw new ProtocolViolationException($"Illegal payload size: payload size exeeded whats max allowed {dataExpected} > {ClientOptions.MaxPacketSize}"); } else if (dataExpected < ClientOptions.MinPacketSize) { throw new ProtocolViolationException($"Illegal payload size: payload size is less than allowed {dataExpected} < {ClientOptions.MinPacketSize}"); } else if (dataExpected == 0) { throw new ProtocolViolationException("Illegal payload size: payload had no length"); } else { /*If the expected data size is bigger than what * we can hold we need to write it to a resizable stream */ if (dataExpected > buffer.Length) { //Initialize a new MemStream to receive chunks of the payload payloadStream = new MemoryStream(ClientOptions.BufferSize); //Start the receive loop of the payload socket.BeginReceive(buffer, 0, buffer.Length, 0, ReceivePayloadStreamCallback, null); } else { //Else we receive directly into the buffer socket.BeginReceive(buffer, 0, dataExpected, 0, ReceivePayloadBufferedCallback, null); } } } } catch (NullReferenceException) { return; } catch (ObjectDisposedException) { return; } catch (Exception ex) { HandleDisconnect(ex); } }
private void ProtocolClient_PingUpdated(ProtocolClient sender, double ping) { PingUpdated?.Invoke(sender, ping); }