コード例 #1
0
        public void InEvent()
        {
            //  If still handshaking, receive and process the greeting message.
            if (m_handshaking)
            {
                if (!Handshake())
                {
                    return;
                }
            }

            Debug.Assert(m_decoder != null);
            bool disconnection = false;
            int  processed;

            //  If there's no data to process in the buffer...
            if (m_insize == 0)
            {
                //  Retrieve the buffer and read as much data as possible.
                //  Note that buffer can be arbitrarily large. However, we assume
                //  the underlying TCP layer has fixed buffer size and thus the
                //  number of bytes read will be always limited.
                m_decoder.GetBuffer(ref m_inpos, ref m_insize);
                m_insize = Read(m_inpos, m_insize);

                //  Check whether the peer has closed the connection.
                if (m_insize == -1)
                {
                    m_insize      = 0;
                    disconnection = true;
                }
            }

            if (m_options.RawSocket)
            {
                if (m_insize == 0 || !m_decoder.MessageReadySize(m_insize))
                {
                    processed = 0;
                }
                else
                {
                    processed = m_decoder.ProcessBuffer(m_inpos, m_insize);
                }
            }
            else
            {
                //  Push the data to the decoder.
                processed = m_decoder.ProcessBuffer(m_inpos, m_insize);
            }

            if (processed == -1)
            {
                disconnection = true;
            }
            else
            {
                //  Stop polling for input if we got stuck.
                if (processed < m_insize)
                {
                    m_ioObject.ResetPollin(m_handle);
                }

                m_inpos.AdvanceOffset(processed);
                m_insize -= processed;
            }

            //  Flush all messages the decoder may have produced.
            m_session.Flush();

            //  An input error has occurred. If the last decoded message
            //  has already been accepted, we terminate the engine immediately.
            //  Otherwise, we stop waiting for socket events and postpone
            //  the termination until after the message is accepted.
            if (disconnection)
            {
                if (m_decoder.Stalled())
                {
                    m_ioObject.RmFd(m_handle);
                    m_inputError = true;
                }
                else
                {
                    Error();
                }
            }
        }
コード例 #2
0
        public void InEvent()
        {
            if (m_pendingBytes > 0)
            {
                return;
            }

            //  Get new batch of data.
            //  Note the workaround made not to break strict-aliasing rules.
            data.Reset();

            int received = 0;

            try
            {
                received = m_handle.Receive((byte[])data);
            }
            catch (SocketException ex)
            {
                if (ex.SocketErrorCode == SocketError.WouldBlock)
                {
                    return;
                    //break;
                }
                else
                {
                    m_joined = false;
                    Error();
                    return;
                }
            }

            //  No data to process. This may happen if the packet received is
            //  neither ODATA nor ODATA.
            if (received == 0)
            {
                return;
            }

            //  Read the offset of the fist message in the current packet.
            Debug.Assert(received >= sizeof(ushort));
            ushort offset = data.GetUnsignedShort(m_options.Endian, 0);

            data.AdvanceOffset(sizeof(ushort));
            received -= sizeof(ushort);

            //  Join the stream if needed.
            if (!m_joined)
            {
                //  There is no beginning of the message in current packet.
                //  Ignore the data.
                if (offset == 0xffff)
                {
                    return;
                }

                Debug.Assert(offset <= received);
                Debug.Assert(m_decoder == null);

                //  We have to move data to the begining of the first message.
                data.AdvanceOffset(offset);
                received -= offset;

                //  Mark the stream as joined.
                m_joined = true;

                //  Create and connect decoder for the peer.
                m_decoder = new Decoder(0, m_options.Maxmsgsize, m_options.Endian);
                m_decoder.SetMsgSink(m_session);
            }

            //  Push all the data to the decoder.
            int processed = m_decoder.ProcessBuffer(data, received);

            if (processed < received)
            {
                //  Save some state so we can resume the decoding process later.
                m_pendingBytes = received - processed;
                m_pendingData  = new ByteArraySegment(data, processed);

                //  Stop polling.
                m_ioObject.ResetPollin(m_handle);

                return;
            }

            m_session.Flush();
        }