/// <summary> /// This method is be called when a message receive operation has been completed. /// </summary> /// <param name="socketError">a SocketError value that indicates whether Success or an error occurred</param> /// <param name="bytesTransferred">the number of bytes that were transferred</param> public void InCompleted(SocketError socketError, int bytesTransferred) { if (socketError != SocketError.Success || bytesTransferred == 0) { m_joined = false; Error(); } else { // Read the offset of the fist message in the current packet. Debug.Assert(bytesTransferred >= sizeof(ushort)); ushort offset = m_data.GetUnsignedShort(m_options.Endian, 0); m_data.AdvanceOffset(sizeof(ushort)); bytesTransferred -= 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) { BeginReceive(); return; } Debug.Assert(offset <= bytesTransferred); Debug.Assert(m_decoder == null); // We have to move data to the beginning of the first message. m_data.AdvanceOffset(offset); bytesTransferred -= offset; // Mark the stream as joined. m_joined = true; // Create and connect decoder for the peer. m_decoder = new V1Decoder(0, m_options.MaxMessageSize, m_options.Endian); m_decoder.SetMsgSink(m_session); } // Push all the data to the decoder. int processed = m_decoder.ProcessBuffer(m_data, bytesTransferred); if (processed < bytesTransferred) { // Save some state so we can resume the decoding process later. m_pendingBytes = bytesTransferred - processed; m_pendingData = new ByteArraySegment(m_data, processed); m_state = State.Stuck; } else { m_session.Flush(); BeginReceive(); } } }
private void Error() { Debug.Assert(m_session != null); m_session.Detach(); m_ioObject.RemoveSocket(m_handle); // Disconnect from I/O threads poller object. m_ioObject.Unplug(); // Disconnect from session object. m_decoder?.SetMsgSink(null); m_session = null; m_state = State.Error; Destroy(); }