private void ReadCallback(IAsyncResult ar) { ConnectedClient player = (ConnectedClient)ar.AsyncState; try { Socket handler = player.workSocket; // Read data from the client socket. int bytesRead = handler.EndReceive(ar); //Logger.Debug($"READ {bytesRead} BYTES"); if (bytesRead > 0) { var currentBytes = new byte[bytesRead]; Buffer.BlockCopy(player.buffer, 0, currentBytes, 0, bytesRead); player.accumulatedBytes.AddRange(currentBytes); if (player.accumulatedBytes.Count >= Packet.packetHeaderSize) { //If we're not at the start of a packet, increment our position until we are, or we run out of bytes var accumulatedBytes = player.accumulatedBytes.ToArray(); while (!Packet.StreamIsAtPacket(accumulatedBytes) && accumulatedBytes.Length >= Packet.packetHeaderSize) { player.accumulatedBytes.RemoveAt(0); accumulatedBytes = player.accumulatedBytes.ToArray(); } while (accumulatedBytes.Length >= Packet.packetHeaderSize && Packet.PotentiallyValidPacket(accumulatedBytes)) { Packet readPacket = null; try { readPacket = Packet.FromBytes(accumulatedBytes); PacketReceived?.Invoke(player, readPacket); } catch (Exception e) { Logger.Error(e.Message); Logger.Error(e.StackTrace); } //Remove the bytes which we've already used from the accumulated List //If the packet failed to parse, skip the header so that the rest of the packet is consumed by the above vailidity check on the next run player.accumulatedBytes.RemoveRange(0, readPacket?.Size ?? Packet.packetHeaderSize); accumulatedBytes = player.accumulatedBytes.ToArray(); } } // Not all data received. Get more. handler.BeginReceive(player.buffer, 0, ConnectedClient.BufferSize, 0, new AsyncCallback(ReadCallback), player); } else { //Reading zero bytes is a sign of disconnect ClientDisconnected_Internal(player); } } catch (Exception e) { Logger.Debug(e.ToString()); ClientDisconnected_Internal(player); } }