예제 #1
0
        async void read()
        {
            int rx = 0;

            byte[] b = new byte[4096];

            while (true)
            {
                try {
                    rx = await clientStream.ReadAsync(b, 0, b.Length);
                } catch {
                    rx = -1;
                }

                if (rx > 0)
                {
                    Console.WriteLine("RX: {0} bytes", rx);

                    for (int 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

                        // Don't need the flags yet
                        //var frameFlags = data [4]; // 5th byte is FLAGS

                        // we need to turn the stream id into a uint
                        var frameStreamIdData = new byte[4];
                        Array.Copy(data, 5, frameStreamIdData, 0, 4);
                        uint frameStreamId = Util.ConvertFromUInt31(frameStreamIdData.EnsureBigEndian());

                        Frame frame = null;

                        var ft = (FrameType)frameType;

                        switch (ft)
                        {
                        case FrameType.Data:
                            frame = new DataFrame();
                            break;

                        case FrameType.Headers:
                            frame = new HeadersFrame();
                            break;

                        case FrameType.Priority:
                            frame = new PriorityFrame();
                            break;

                        case FrameType.RstStream:
                            frame = new RstStreamFrame();
                            break;

                        case FrameType.Settings:
                            frame = new SettingsFrame();
                            break;

                        case FrameType.PushPromise:
                            frame = new PushPromiseFrame();
                            break;

                        case FrameType.Ping:
                            frame = new PingFrame();
                            break;

                        case FrameType.GoAway:
                            frame = new GoAwayFrame();
                            break;

                        case FrameType.WindowUpdate:
                            frame = new WindowUpdateFrame();
                            break;

                        case FrameType.Continuation:
                            frame = new ContinuationFrame();
                            break;
                        }

                        try {
                            // Call the specific subclass implementation to parse
                            if (frame != null)
                            {
                                frame.Parse(data);
                            }
                        } catch (Exception ex) {
                            Console.WriteLine("Parsing Frame Failed: " + ex);
                            throw ex;
                        }

                        // If we are waiting on the connection preface from server
                        // and it's the right frame type, set our resetevent
                        if (ft == FrameType.Settings &&
                            resetEventConnectionSettingsFrame != null &&
                            !resetEventConnectionSettingsFrame.IsSet)
                        {
                            var settingsFrame = frame as SettingsFrame;
                            // ack the settings from the server
                            settingsFrame.Ack = true;
                            await SendFrame(settingsFrame);

                            resetEventConnectionSettingsFrame.Set();
                        }

                        try {
                            if (frameStreamId == 0)
                            {
                                foreach (var s in Streams)
                                {
                                    if (s.Value.State != StreamState.Closed)
                                    {
                                        s.Value.ProcessFrame(frame);
                                    }
                                }
                            }
                            else
                            {
                                var stream = await GetStream(frameStreamId);

                                stream.ProcessFrame(frame);
                            }
                        } catch (Exception ex) {
                            Console.WriteLine("Error Processing Frame: " + ex);
                            throw ex;
                        }
                    }
                }
                else
                {
                    // TODO: Connection error
                    //throw new Exception ("Connection Error");
                    break;
                }
            }

            Disconnect();
        }
예제 #2
0
        async void read ()
        {                        
            int rx = 0;
            byte[] b = new byte[4096];

            while (true) {

                try {
                    rx = await clientStream.ReadAsync(b, 0, b.Length);
                } catch {
                    rx = -1;
                }

                if (rx > 0) {

                    Console.WriteLine ("RX: {0} bytes", rx);

                    for (int 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

                        // Don't need the flags yet
                        //var frameFlags = data [4]; // 5th byte is FLAGS

                        // we need to turn the stream id into a uint
                        var frameStreamIdData = new byte[4]; 
                        Array.Copy (data, 5, frameStreamIdData, 0, 4);
                        uint frameStreamId = Util.ConvertFromUInt31 (frameStreamIdData.EnsureBigEndian ());

                        Frame frame = null;

                        var ft = (FrameType)frameType;

                        switch (ft) {
                        case FrameType.Data:
                            frame = new DataFrame ();
                            break;
                        case FrameType.Headers:
                            frame = new HeadersFrame ();
                            break;
                        case FrameType.Priority:
                            frame = new PriorityFrame ();
                            break;
                        case FrameType.RstStream:
                            frame = new RstStreamFrame ();
                            break;
                        case FrameType.Settings:
                            frame = new SettingsFrame ();
                            break;
                        case FrameType.PushPromise:
                            frame = new PushPromiseFrame ();
                            break;
                        case FrameType.Ping:
                            frame = new PingFrame ();
                            break;
                        case FrameType.GoAway:
                            frame = new GoAwayFrame ();
                            break;
                        case FrameType.WindowUpdate:
                            frame = new WindowUpdateFrame ();
                            break;
                        case FrameType.Continuation:
                            frame = new ContinuationFrame ();
                            break;
                        }

                        try {
                            // Call the specific subclass implementation to parse
                            if (frame != null)
                                frame.Parse (data);
                        } catch (Exception ex) {
                            Console.WriteLine ("Parsing Frame Failed: " + ex);
                            throw ex;
                        }

                        // If we are waiting on the connection preface from server
                        // and it's the right frame type, set our resetevent
                        if (ft == FrameType.Settings 
                            && resetEventConnectionSettingsFrame != null 
                            && !resetEventConnectionSettingsFrame.IsSet) {

                            var settingsFrame = frame as SettingsFrame;
                            // ack the settings from the server
                            settingsFrame.Ack = true;
                            await SendFrame (settingsFrame);
                            resetEventConnectionSettingsFrame.Set ();
                        }

                        try {
                            if (frameStreamId == 0) {
                                foreach (var s in Streams) {
                                    if (s.Value.State != StreamState.Closed)
                                        s.Value.ProcessFrame(frame);
                                }
                            } else {
                                var stream = await GetStream(frameStreamId);
                                stream.ProcessFrame(frame);
                            }
                        } catch (Exception ex) {
                            Console.WriteLine ("Error Processing Frame: " + ex);
                            throw ex;
                        }
                    }

                } else {
                    // TODO: Connection error
                    //throw new Exception ("Connection Error");
                    break;
                }


            }

            Disconnect();
        }