/// <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(); } } }
void ProcessInput() { while (m_pendingBytes > 0) { var result = m_decoder.Decode(m_pendingData, m_pendingBytes, out var processed); m_pendingData.AdvanceOffset(processed); m_pendingBytes -= processed; if (result == DecodeResult.Error) { m_joined = false; Error(); return; } if (result == DecodeResult.Processing) { break; } var pushResult = m_decoder.PushMsg(m_session.PushMsg); if (pushResult == PushMsgResult.Full) { m_state = State.Stuck; m_session.Flush(); return; } else if (pushResult == PushMsgResult.Error) { m_joined = false; Error(); return; } } m_session.Flush(); BeginReceive(); }