private void OnReceive(IAsyncResult result) { SocketState state = result.AsyncState as SocketState; if (state == null) { Tracer.Warn("Socket state was null."); return; } try { Socket socket = state.Socket; if (socket.Connected == false) { Disconnect(); return; } int length = socket.EndReceive(result); if (length > 0) { byte[] buffer = state.Buffer; if (m_IsDecompressionEnabled) { DecompressBuffer(ref buffer, ref length); } if (m_IncompletePacket.Length > 0) { m_IncompletePacket.Prepend(buffer, length); m_IncompletePacket.Clear(); } int offset = 0; ProcessBuffer(buffer, ref offset, length); // Not all the data was processed, due to an incomplete packet if (offset < length) { m_IncompletePacket.Write(buffer, offset, length - offset); } } if (m_ServerSocket != null) { m_ServerSocket.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, OnReceive, state); } } catch (Exception e) { Tracer.Debug(e.ToString()); Disconnect(); } }
void DecompressBuffer(ref byte[] buffer, ref int length) { byte[] source = m_BufferPool.AcquireBuffer(); int incompleteLength = m_IncompleteDecompressionPacket.Length; int sourceLength = incompleteLength + length; if (incompleteLength > 0) { m_IncompleteDecompressionPacket.Prepend(source, 0); m_IncompleteDecompressionPacket.Clear(); } Buffer.BlockCopy(buffer, 0, source, incompleteLength, length); int outSize; int processedOffset = 0; int sourceOffset = 0; int offset = 0; while (m_Decompression.DecompressChunk(ref source, ref sourceOffset, sourceLength, ref buffer, offset, out outSize)) { processedOffset = sourceOffset; offset += outSize; } length = offset; // We've run out of data to parse, or the packet was incomplete. If the packet was incomplete, // we should save what's left for the next socket receive event. if (processedOffset >= sourceLength) { m_BufferPool.ReleaseBuffer(source); return; } m_IncompleteDecompressionPacket.Write(source, processedOffset, sourceLength - processedOffset); }