private void Receive()
        {
            ClientState = ClientState.Listening;

            while (true)
            {
                try
                {
                    _tokenSource.Token.ThrowIfCancellationRequested();
                    IPEndPoint endPoint = null;
                    byte[]     buffer   = _client.Receive(ref endPoint);
                    IPacket    packet   = _packetFactory.GetPacket(buffer[0]);
                    packet.Decode(buffer);

                    if (packet is ConnectionRequestPacket connectionRequestPacket)
                    {
                        int mtu = connectionRequestPacket.Padding.Length + 77;
                        Send(endPoint, new ConnectionResponsePacket((ushort)mtu));
                        if (!_sessions.ContainsKey(endPoint))
                        {
                            _sessions[endPoint] = new ReliabilityUdpClientSession(endPoint, (ushort)mtu, this,
                                                                                  _receiveCustomDataPacketCallback);
                        }
                    }
                    else if (packet is ConnectionResponsePacket connectionEstablishmentPacket)
                    {
                        if (_sessions.ContainsKey(endPoint))
                        {
                            throw new InvalidPacketException("Now connected.");
                        }

                        _sessions[endPoint] =
                            new ReliabilityUdpClientSession(endPoint, connectionEstablishmentPacket.MtuSize, this,
                                                            _receiveCustomDataPacketCallback);
                        _connectionCallback?.Invoke(new ConnectionData(endPoint,
                                                                       connectionEstablishmentPacket.MtuSize));

                        _sessions[endPoint].SendPacket(new ConnectionEstablishmentPacket());
                    }
                    else if (packet is DataPacket dataPacket)
                    {
                        if (_sessions.ContainsKey(endPoint))
                        {
                            _sessions[endPoint].OnReceive(dataPacket);
                        }
                    }
                    else if (packet is NackPacket nackPacket)
                    {
                        if (_sessions.ContainsKey(endPoint))
                        {
                            _sessions[endPoint].OnNack(nackPacket);
                        }
                    }
                    else if (packet is AckPacket ackPacket)
                    {
                        if (_sessions.ContainsKey(endPoint))
                        {
                            _sessions[endPoint].OnAck(ackPacket);
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
        }