Esempio n. 1
0
            internal ServerClientStateObject Rent()
            {
                ServerClientStateObject buffer = null;
                bool lockTaken = false;

                try
                {
                    _lock.Enter(ref lockTaken);

                    if (_index < _buffers.Length)
                    {
                        buffer             = _buffers[_index];
                        _buffers[_index++] = null;
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        _lock.Exit(false);
                    }
                }

                return(buffer ?? new ServerClientStateObject
                {
                    Buffer = new byte[_maxPacketSize], EndPoint = new IPEndPoint(IPAddress.Any, 0)
                });
            }
Esempio n. 2
0
        private void AcceptCallback(IAsyncResult ar)
        {
            try
            {
                Socket socket = _listener.EndAccept(ar);
                ServerClientStateObject state = new ServerClientStateObject
                {
                    //0.2mb
                    Socket         = socket,
                    BufferWrite    = new byte[_maxPacketSize],
                    BufferRead     = new byte[_maxPacketSize],
                    CircularBuffer = new CircularBuffer(_maxPacketSize * 2)
                };

                ReceiveAsync(state);
            }
            catch (ObjectDisposedException)
            {
                /* SOCKET CLOSED */
                return;
            }
            catch
            {
                /* IGNORE */
            }

            ListenAsync();
        }
Esempio n. 3
0
 private void ReceiveAsync(ServerClientStateObject state)
 {
     if ((_state & RECEIVE_FLAG) == RECEIVE_FLAG)
     {
         try
         {
             state.Socket.BeginReceive(
                 state.BufferWrite, 0, state.BufferWrite.Length, SocketFlags.None, ReceiveDataCallback, state);
         }
         catch (ObjectDisposedException) { InvokeClientDisconnect(state.Socket, DisconnectReason.Aborted); }
         catch (SocketException) { InvokeClientDisconnect(state.Socket, DisconnectReason.Error); }
         catch { InvokeClientDisconnect(state.Socket, DisconnectReason.Unspecified); }
     }
 }
Esempio n. 4
0
        /// <summary>
        ///     Receives.
        /// </summary>
        /// <param name="socket">           The socket. </param>
        /// <param name="buffer">           The buffer. </param>
        /// <param name="bytesTransferred"> The bytes transferred. </param>
        /// <param name="state">            The state. </param>
        private protected unsafe void Receive(Socket socket,
                                              byte[]                  buffer,
                                              int bytesTransferred,
                                              ServerClientStateObject state)
        {
            DeserializePacketInfo deserializePacketInfo;
            int size = state.CircularBuffer.Write(buffer, 0, bytesTransferred);

            while (state.CircularBuffer.PeekHeader(
                       0, out byte packetHeader, out deserializePacketInfo.CommandID,
                       out deserializePacketInfo.Length, out ushort checksum) &&
                   deserializePacketInfo.Length <= state.CircularBuffer.Count - Constants.TCP_HEADER_SIZE)
            {
                if (state.CircularBuffer.PeekByte(
                        (Constants.TCP_HEADER_SIZE + deserializePacketInfo.Length) - 1, out byte b) &&
                    b == Constants.ZERO_BYTE)
                {
                    fixed(byte *ptr = state.BufferRead)
                    {
                        state.CircularBuffer.Read(ptr, deserializePacketInfo.Length, Constants.TCP_HEADER_SIZE);
                        if (size < bytesTransferred)
                        {
                            state.CircularBuffer.Write(buffer, size, bytesTransferred - size);
                        }
                    }

                    if (Serialization.Serialization.DeserializeTcp(
                            packetHeader, checksum, state.BufferRead, state.BigDataHandler,
                            out deserializePacketInfo.Data, ref deserializePacketInfo.Length,
                            out deserializePacketInfo.ResponseID))
                    {
                        DeserializeData(socket, in deserializePacketInfo);
                    }

                    continue;
                }
                bool skipped = state.CircularBuffer.SkipUntil(Constants.TCP_HEADER_SIZE, Constants.ZERO_BYTE);
                if (size < bytesTransferred)
                {
                    size += state.CircularBuffer.Write(buffer, size, bytesTransferred - size);
                }
                if (!skipped && !state.CircularBuffer.SkipUntil(0, Constants.ZERO_BYTE))
                {
                    break;
                }
            }
        }
Esempio n. 5
0
        private void ReceiveDataCallback(IAsyncResult iar)
        {
            ServerClientStateObject state = (ServerClientStateObject)iar.AsyncState !;
            int bytesTransferred;

            try
            {
                if ((bytesTransferred = _listener !.EndReceiveFrom(iar, ref state.EndPoint)) <= 0)
                {
                    InvokeClientDisconnect(state.EndPoint, DisconnectReason.Graceful);
                    _serverClientStateObjectPool.Return(state);
                    return;
                }
            }
            catch (ObjectDisposedException)
            {
                InvokeClientDisconnect(state.EndPoint, DisconnectReason.Aborted);
                _serverClientStateObjectPool.Return(state);
                return;
            }
            catch (SocketException)
            {
                InvokeClientDisconnect(state.EndPoint, DisconnectReason.Error);
                _serverClientStateObjectPool.Return(state);
                return;
            }
            catch
            {
                InvokeClientDisconnect(state.EndPoint, DisconnectReason.Unspecified);
                _serverClientStateObjectPool.Return(state);
                return;
            }

            ListenAsync();

            if (Serialization.Serialization.DeserializeUdp(
                    state.Buffer, bytesTransferred, _bigDataHandler, i => (state.EndPoint, i),
                    out DeserializePacketInfo deserializePacketInfo))
            {
                DeserializeData(state.EndPoint, in deserializePacketInfo);
            }

            _serverClientStateObjectPool.Return(state);
        }
Esempio n. 6
0
        private protected override void ListenAsync()
        {
            ServerClientStateObject state = _pool.Rent();

            try
            {
                _listener.BeginReceiveFrom(
                    state.Buffer, 0, state.Buffer.Length, SocketFlags.None, ref state.EndPoint,
                    ReceiveDataCallback, state);
            }
            catch (ObjectDisposedException)
            {
                InvokeClientDisconnect(state.EndPoint, DisconnectReason.Aborted);
            }
            catch (SocketException)
            {
                InvokeClientDisconnect(state.EndPoint, DisconnectReason.Error);
            }
            catch { InvokeClientDisconnect(state.EndPoint, DisconnectReason.Unspecified); }
        }
Esempio n. 7
0
            internal void Return(ServerClientStateObject obj)
            {
                bool lockTaken = false;

                try
                {
                    _lock.Enter(ref lockTaken);

                    if (_index != 0)
                    {
                        obj.EndPoint       = new IPEndPoint(IPAddress.Any, 0);
                        _buffers[--_index] = obj;
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        _lock.Exit(false);
                    }
                }
            }
Esempio n. 8
0
        private unsafe void ReceiveDataCallback(IAsyncResult iar)
        {
            ServerClientStateObject state = (ServerClientStateObject)iar.AsyncState;
            int length;

            try
            {
                if ((length = state.Socket.EndReceive(iar)) <= 0)
                {
                    InvokeClientDisconnect(state.Socket, DisconnectReason.Graceful);
                    return;
                }
            }
            catch (ObjectDisposedException)
            {
                InvokeClientDisconnect(state.Socket, DisconnectReason.Aborted);
                return;
            }
            catch (SocketException)
            {
                InvokeClientDisconnect(state.Socket, DisconnectReason.Error);
                return;
            }
            catch
            {
                InvokeClientDisconnect(state.Socket, DisconnectReason.Unspecified);
                return;
            }

            CircularBuffer circularBuffer = state.CircularBuffer;
            int            size           = circularBuffer.Write(state.BufferWrite, 0, length);

            while (circularBuffer.PeekHeader(
                       0, out byte packetHeader, out uint commandID, out int dataLength, out ushort checksum) &&
                   dataLength <= circularBuffer.Count - Constants.TCP_HEADER_SIZE)
            {
                if (circularBuffer.PeekByte((Constants.TCP_HEADER_SIZE + dataLength) - 1, out byte b) &&
                    b == Constants.ZERO_BYTE)
                {
                    fixed(byte *ptr = state.BufferRead)
                    {
                        circularBuffer.Read(ptr, 0, dataLength, Constants.TCP_HEADER_SIZE);
                        if (size < length)
                        {
                            circularBuffer.Write(state.BufferWrite, size, length - size);
                        }

                        uint responseID = 0;
                        int  offset     = 0;

                        if ((packetHeader & Serialization.Serialization.RESPONSE_BIT_MASK) != 0)
                        {
                            responseID = *(uint *)ptr;
                            offset     = 4;
                        }

                        CompressionMode compressionMode =
                            (CompressionMode)(packetHeader & Serialization.Serialization.COMPRESSED_MODE_MASK);

                        if (compressionMode != CompressionMode.None)
                        {
                            offset += 4;
                        }

                        byte[] deserializeBuffer = ByteArrayPool.Rent(dataLength);
                        if (Serialization.Serialization.S2E(
                                ptr, offset, dataLength - 1, deserializeBuffer, out int bufferLength) == checksum)
                        {
                            switch (compressionMode)
                            {
                            case CompressionMode.Lz4:
                                int l = *(int *)(ptr + offset);

                                byte[] buffer = ByteArrayPool.Rent(l);
                                int    s      = LZ4Codec.Decode(
                                    deserializeBuffer, 0, bufferLength, buffer, 0, l, true);
                                if (s != l)
                                {
                                    throw new Exception("LZ4.Decode FAILED!");
                                }

                                ByteArrayPool.Return(deserializeBuffer);
                                deserializeBuffer = buffer;
                                bufferLength      = l;
                                break;
                            }

                            ReceiveAsync(state);
                            DeserializeData(state.Socket, commandID, deserializeBuffer, 0, bufferLength, responseID);
                            return;
                        }
                        break;
                    }
                }
                bool skipped = circularBuffer.SkipUntil(Constants.TCP_HEADER_SIZE, Constants.ZERO_BYTE);
                if (size < length)
                {
                    size += circularBuffer.Write(state.BufferWrite, size, length - size);
                }
                if (!skipped && !circularBuffer.SkipUntil(0, Constants.ZERO_BYTE))
                {
                    break;
                }
            }
            ReceiveAsync(state);
        }
Esempio n. 9
0
        private unsafe void ReceiveAsyncCompleted(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError != SocketError.Success)
            {
                InvokeClientDisconnect(e.AcceptSocket, DisconnectReason.Error);
                return;
            }
            int length = e.BytesTransferred;

            if (length <= 0)
            {
                InvokeClientDisconnect(e.AcceptSocket, DisconnectReason.Graceful);
                return;
            }

            ServerClientStateObject state          = (ServerClientStateObject)e.UserToken;
            CircularBuffer          circularBuffer = state.CircularBuffer;

            int size = circularBuffer.Write(e.Buffer, 0, length);

            while (circularBuffer.PeekHeader(
                       0, out byte packetHeader, out uint commandID, out int dataLength, out ushort checksum) &&
                   dataLength <= circularBuffer.Count - Constants.TCP_HEADER_SIZE)
            {
                if (circularBuffer.PeekByte((Constants.TCP_HEADER_SIZE + dataLength) - 1, out byte b) &&
                    b == Constants.ZERO_BYTE)
                {
                    fixed(byte *ptr = state.BufferRead)
                    {
                        circularBuffer.Read(ptr, 0, dataLength, Constants.TCP_HEADER_SIZE);
                        if (size < length)
                        {
                            circularBuffer.Write(e.Buffer, size, length - size);
                        }

                        uint responseID = 0;
                        int  offset     = 0;

                        if ((packetHeader & Serialization.Serialization.RESPONSE_BIT_MASK) != 0)
                        {
                            responseID = *(uint *)ptr;
                            offset     = 4;
                        }

                        CompressionMode compressionMode =
                            (CompressionMode)(packetHeader & Serialization.Serialization.COMPRESSED_MODE_MASK);

                        if (compressionMode != CompressionMode.None)
                        {
                            offset += 4;
                        }

                        byte[] deserializeBuffer = ByteArrayPool.Rent(dataLength);
                        if (Serialization.Serialization.S2E(
                                ptr, offset, dataLength - 1, deserializeBuffer, out int bufferLength) == checksum)
                        {
                            switch (compressionMode)
                            {
                            case CompressionMode.Lz4:
                                int l = *(int *)(ptr + offset);

                                byte[] buffer = ByteArrayPool.Rent(l);
                                int    s      = LZ4Codec.Decode(
                                    deserializeBuffer, 0, bufferLength, buffer, 0, l, true);
                                if (s != l)
                                {
                                    throw new Exception("LZ4.Decode FAILED!");
                                }

                                ByteArrayPool.Return(deserializeBuffer);
                                deserializeBuffer = buffer;
                                bufferLength      = l;
                                break;
                            }

                            ReceiveAsync(e);
                            DeserializeData(e.AcceptSocket, commandID, deserializeBuffer, 0, bufferLength, responseID);
                            return;
                        }
                        break;
                    }
                }
                bool skipped = circularBuffer.SkipUntil(Constants.TCP_HEADER_SIZE, Constants.ZERO_BYTE);
                if (size < length)
                {
                    size += circularBuffer.Write(e.Buffer, size, length - size);
                }
                if (!skipped && !circularBuffer.SkipUntil(0, Constants.ZERO_BYTE))
                {
                    break;
                }
            }
            ReceiveAsync(e);
        }
Esempio n. 10
0
        private unsafe void ReceiveDataCallback(IAsyncResult iar)
        {
            ServerClientStateObject state = (ServerClientStateObject)iar.AsyncState;

            int length;

            try
            {
                if ((length = _listener.EndReceiveFrom(iar, ref state.EndPoint)) <= 0)
                {
                    InvokeClientDisconnect(state.EndPoint, DisconnectReason.Graceful);
                    return;
                }
            }
            catch (ObjectDisposedException)
            {
                InvokeClientDisconnect(state.EndPoint, DisconnectReason.Aborted);
                return;
            }
            catch (SocketException)
            {
                InvokeClientDisconnect(state.EndPoint, DisconnectReason.Error);
                return;
            }
            catch
            {
                InvokeClientDisconnect(state.EndPoint, DisconnectReason.Unspecified);
                return;
            }

            ListenAsync();

            state.Buffer.GetHeaderUdp(out byte packetHeader, out uint commandID, out int dataLength);

            if (length == dataLength + Constants.UDP_HEADER_SIZE)
            {
                EndPoint ep = state.EndPoint;

                uint responseID = 0;
                int  offset     = 0;
                fixed(byte *src = state.Buffer)
                {
                    if ((packetHeader & Serialization.Serialization.RESPONSE_BIT_MASK) != 0)
                    {
                        responseID = *(uint *)src;
                        offset     = 4;
                    }
                    byte[] payload;
                    switch ((CompressionMode)(packetHeader & Serialization.Serialization.COMPRESSED_MODE_MASK))
                    {
                    case CompressionMode.Lz4:
                        int l = *(int *)(src + offset);
                        offset += 4;

                        payload = ByteArrayPool.Rent(l);
                        int s = LZ4Codec.Decode(
                            state.Buffer, Constants.UDP_HEADER_SIZE + offset, dataLength - offset, payload, 0, l,
                            true);
                        if (s != l)
                        {
                            throw new Exception("LZ4.Decode FAILED!");
                        }

                        DeserializeData(ep, commandID, payload, 0, l, responseID);
                        break;

                    case CompressionMode.None:
                    default:
                        dataLength -= offset;
                        payload     = ByteArrayPool.Rent(dataLength);

                        fixed(byte *dest = payload)
                        {
                            Mem.Cpy(dest, src + Constants.UDP_HEADER_SIZE + offset, dataLength);
                        }

                        DeserializeData(ep, commandID, payload, 0, dataLength, responseID);
                        break;
                    }
                }
            }

            _pool.Return(state);
        }