/// <summary> /// Tries to pre-process a datagram without further parsing and processing. /// </summary> /// <param name="processor"> The inbound processor for the datagram to be pre-processed. </param> /// <returns> True if it was pre-processed and no further processing is needed; false otherwise. </returns> private bool TryPreProcessInboundDatagram(InboundProcessor processor) { if (!processor.ValidateLength()) { this.rconClient.OnConnectionProblem(new ConnectionProblemEventArgs(ConnectionProblemType.InvalidLength)); this.Log.Trace("INVALID datagram received"); return true; } this.Metrics.InboundDatagramCount++; #if DEBUG if (processor.IsShutDownDatagram && this.ShutdownReason == ShutdownReason.None) { this.Log.Trace("SHUTDOWN DATAGRAM RECEIVED - SHUTTING DOWN."); this.ShutdownReason = ShutdownReason.ServerRequested; return true; } #endif if (processor.TryPreProcess(this.DiscardConsoleMessages, this.ConMsgsTracker, this.CmdsTracker)) { return true; } if (!processor.VerifyCrc()) { this.rconClient.OnConnectionProblem(new ConnectionProblemEventArgs(ConnectionProblemType.Corrupted)); return true; } return false; }
private async Task ReceiveDatagramAsync() { this.Log.Trace("BEFORE await ReceiveAsync"); // ReceiveAsync (BeginRead) will spawn a new thread // which blocks head-on against the IO Completion Port // http://msdn.microsoft.com/en-us/library/windows/desktop/aa364986(v=vs.85).aspx UdpReceiveResult result = await this.UdpClient.ReceiveAsync() //// do not incurr ANOTHER context switch cost .ConfigureAwait(false); // Async continuation; we are probably in a different thread now this.Log.Trace("AFTER await ReceiveAsync"); var processor = new InboundProcessor(result.Buffer, this.datagramSender, this.Log); if (this.TryPreProcessInboundDatagram(processor)) { return; } var concreteDgram = processor.Parse(); this.Metrics.ParsedDatagramsCount++; this.Dispatch(concreteDgram); }