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) }); }
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(); }
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); } } }
/// <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; } } }
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); }
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); } }
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); } } }
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); }
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); }
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); }