Example #1
0
        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);
        }