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(); } } }
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(); }