private static void AcceptCallback(IAsyncResult ar)
        {
            // Signal the main thread to continue.
            AllDone.Set();

            // Get the socket that handles the client request.
            Socket listener = (Socket)ar.AsyncState;
            Socket handler  = listener.EndAccept(ar);

            // Create the state object.
            PhobosClient state = new PhobosClient
            {
                WorkSocket = handler
            };

            handler.BeginReceive(state.Buffer, 0, PhobosClient.BUFFER_SIZE, 0, ReadCallback, state);
        }
        private static void ReadCallback(IAsyncResult ar)
        {
            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            PhobosClient phobosClient = (PhobosClient)ar.AsyncState;
            Socket       handler      = phobosClient.WorkSocket;

            // Read data from the client socket.
            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)
            {
                using (MemoryStream stream = new MemoryStream(phobosClient.Buffer))
                    using (EndianBinaryReader reader = new EndianBinaryReader(EndianBitConverter.Big, stream))
                    {
                        while (reader.BaseStream.Position < phobosClient.Buffer.Length)
                        {
                            phobosClient.AwaitingData = true;

                            if (phobosClient.CurrentPacketLength <= 0)
                            {
                                phobosClient.CurrentPacketLength = reader.ReadInt32();

                                if (phobosClient.CurrentPacketLength <= 0)
                                {
                                    break;
                                }

                                phobosClient.InProgressPacketBytes.AddRange(EndianBitConverter.Big.GetBytes(phobosClient.CurrentPacketLength));
                            }

                            int remainingBytes = phobosClient.CurrentPacketLength - phobosClient.InProgressPacketBytes.Count;

                            // ReadBytes only returns the available amount of bytes
                            phobosClient.InProgressPacketBytes.AddRange(reader.ReadBytes((remainingBytes > 1024 ? 1024 : remainingBytes) < 0 ? 1024 : remainingBytes));

                            if (phobosClient.CurrentPacketLength != phobosClient.InProgressPacketBytes.Count)
                            {
                                continue;
                            }

                            PacketReceived?.Invoke(phobosClient, new PacketReceivedEventArgs
                            {
                                PhobosPacket = new PhobosPacket(phobosClient.InProgressPacketBytes.ToArray()),
                                Sender       = phobosClient
                            });

                            phobosClient.InProgressPacketBytes.Clear();

                            phobosClient.CurrentPacketLength = -1;
                            phobosClient.AwaitingData        = false;
                        }
                    }

                phobosClient.Buffer = new byte[1024];

                if (phobosClient.AwaitingData)
                {
                    handler.BeginReceive(phobosClient.Buffer, 0, PhobosClient.BUFFER_SIZE, 0, ReadCallback, phobosClient);
                }
                else if (phobosClient.InProgressPacketBytes.Any())
                {
                    PacketReceived?.Invoke(phobosClient, new PacketReceivedEventArgs
                    {
                        PhobosPacket = new PhobosPacket(phobosClient.InProgressPacketBytes.ToArray()),
                        Sender       = phobosClient
                    });

                    phobosClient.InProgressPacketBytes.Clear();
                }
            }
            else if (phobosClient.InProgressPacketBytes.Any())
            {
                PacketReceived?.Invoke(phobosClient, new PacketReceivedEventArgs
                {
                    PhobosPacket = new PhobosPacket(phobosClient.InProgressPacketBytes.ToArray()),
                    Sender       = phobosClient
                });

                phobosClient.InProgressPacketBytes.Clear();
            }
        }