async void Read() { int rx; var b = new byte[4096]; while (true) { try { rx = await clientStream.ReadAsync(b, 0, b.Length).ConfigureAwait(false); } catch { rx = -1; } if (rx > 0) { // Add all the bytes read into our buffer list for (var i = 0; i < rx; i++) { buffer.Add(b [i]); } while (true) { // We need at least 9 bytes to process the frame // 9 octets is the frame header length if (buffer.Count < 9) { break; } // Find out the frame length // which is a 24 bit uint, so we need to convert this as c# uint is 32 bit var flen = new byte[4]; flen [0] = 0x0; flen [1] = buffer.ElementAt(0); flen [2] = buffer.ElementAt(1); flen [3] = buffer.ElementAt(2); var frameLength = BitConverter.ToUInt32(flen.EnsureBigEndian(), 0); // If we are expecting a payload that's bigger than what's in our buffer // we should keep reading from the stream if (buffer.Count - 9 < frameLength) { break; } // If we made it this far, the buffer has all the data we need, let's get it out to process var data = buffer.GetRange(0, (int)frameLength + 9).ToArray(); // remove the processed info from the buffer buffer.RemoveRange(0, (int)frameLength + 9); // Get the Frame Type so we can instantiate the right subclass var frameType = data [3]; // 4th byte in frame header is TYPE // we need to turn the stream id into a uint var frameStreamIdData = new byte[4]; Array.Copy(data, 5, frameStreamIdData, 0, 4); var frameStreamId = Util.ConvertFromUInt31(frameStreamIdData.EnsureBigEndian()); // Create a new typed instance of our abstract Frame var frame = Frame.Create((FrameType)frameType); try { // Call the specific subclass implementation to parse frame.Parse(data); } catch (Exception ex) { Log.Error("Parsing Frame Failed: {0}", ex); throw ex; } Log.Debug("<- {0}", frame); // If it's a settings frame, we should note the values and // return the frame with the Ack flag set if (frame.Type == FrameType.Settings) { var settingsFrame = frame as SettingsFrame; // Update our instance of settings with the new data Settings.UpdateFromFrame(settingsFrame, flowControlManager); // See if this was an ack, if not, return an empty // ack'd settings frame if (!settingsFrame.Ack) { await QueueFrame(new SettingsFrame { Ack = true }).ConfigureAwait(false); } } else if (frame.Type == FrameType.Ping) { var pingFrame = frame as PingFrame; // See if we need to respond to the ping request (if it's not-ack'd) if (!pingFrame.Ack) { // Ack and respond pingFrame.Ack = true; await QueueFrame(pingFrame).ConfigureAwait(false); } } else if (frame.Type == FrameType.Data) { // Increment our received data counter Interlocked.Add(ref receivedDataCount, frame.PayloadLength); } // Some other frame type, just pass it along to the stream var stream = await streamManager.Get(frameStreamId).ConfigureAwait(false); stream.ProcessReceivedFrames(frame); } } else { // Stream was closed, break out of reading loop break; } } // Cleanup Disconnect(); }