private bool OnReceivingFragment(byte[] buffer, IPEndPoint endpointLastsender)
        {
            if (buffer.Length > 4 && buffer[0] == 250 && buffer[1] == 250 && buffer[2] == 250 && buffer[3] == 250)
            {
                MemoryStream bufferStream;
                if (this.m_listfragmentsPerConnection.TryGetValue(endpointLastsender, out bufferStream) == false)
                {
                    if (m_listPoolMemoryStreams.Count == 0)
                    {
                        bufferStream = new MemoryStream();
                    }
                    else
                    {
                        bufferStream = m_listPoolMemoryStreams.Dequeue();
                    }
                    this.m_listfragmentsPerConnection[endpointLastsender] = bufferStream;
                }
                bufferStream.Write(buffer, 4, buffer.Length - 4);
                return(true);
            }

            if (this.m_listfragmentsPerConnection.TryGetValue(endpointLastsender, out MemoryStream ms))
            {
                byte[] bufferEnd = ms.ToArray();
                ListStackPackets.Enqueue(NetworkReceivedPacket.GetPoolObject(endpointLastsender, bufferEnd));
                ms.SetLength(0);
                m_listPoolMemoryStreams.Enqueue(ms);
                this.m_listfragmentsPerConnection.Remove(endpointLastsender);
            }

            return(false);
        }
        private void Receiving(object sender)
        {
            IPEndPoint endpointLastsender = new IPEndPoint(IPAddress.Any, 0);

            byte[] buffer = new byte[1024];

            while (true)
            {
                try
                {
                    if (this.Status && this.BaseSocket != null)
                    {
                        buffer = this.BaseSocket.Receive(ref endpointLastsender);
                        if (this.OnReceivingFragment(buffer, endpointLastsender))
                        {
                            continue;
                        }
                        var packetObject = NetworkReceivedPacket.GetPoolObject(endpointLastsender, buffer);
                        ListStackPackets.Enqueue(packetObject);
                    }
                    else
                    {
                        Thread.Sleep(10);
                    }
                }
                catch { }
            }
        }
        public static NetworkReceivedPacket GetPoolObject(IPEndPoint addres, Byte[] buffer)
        {
            NetworkReceivedPacket callBackObject = null;

            if (ListPoolObjects.Count != 0)
            {
                callBackObject = ListPoolObjects.Dequeue();
            }
            else
            {
                callBackObject = new NetworkReceivedPacket();
            }

            callBackObject.Addres = addres;
            callBackObject.Buffer = buffer;

            return(callBackObject);
        }
        public virtual void Cycle()
        {
            if (this.Status)
            {
                NetworkReceivedPacket packet = null;
                while (this.ListStackPackets.Count != 0)
                {
                    packet = ListStackPackets.Dequeue();

                    if (packet.Buffer != null && packet.Buffer.Length > 1)
                    {
                        switch (packet.Buffer[0])
                        {
                        case 255:
                            if (packet.Buffer[1] == 255 && packet.Buffer.Length > 3 && packet.Buffer[2] == 255 && packet.Buffer[3] == 255)
                            {
                                OnQueryRequest?.Invoke(packet.Addres, packet.Buffer);
                                NetworkReceivedPacket.SetPoolObject(packet);
                                continue;
                            }

                            break;

                        case 254:
                            if (packet.Buffer[1] == 254 && packet.Buffer.Length > 3 && packet.Buffer[2] == 254 && packet.Buffer[3] == 254)
                            {
                                if (this.m_listconnections.TryGetValue(packet.Addres, out var connection))
                                {
                                    string reasone = "Disconnected";
                                    if (packet.Buffer.Length != 4)
                                    {
                                        byte[] reasoneBuffer = new byte[packet.Buffer.Length - 4];
                                        for (int i = 4; i < packet.Buffer.Length; ++i)
                                        {
                                            reasoneBuffer[i - 4] = packet.Buffer[i];
                                        }
                                        reasone = Encoding.ASCII.GetString(reasoneBuffer);
                                    }

                                    this.KickConnection(connection, reasone);
                                }

                                NetworkReceivedPacket.SetPoolObject(packet);
                                continue;
                            }

                            break;

                        case 253:
                            if (packet.Buffer[1] == 253 && packet.Buffer.Length > 4 && packet.Buffer[2] == 253 && packet.Buffer[3] == 253 && packet.Buffer[4] == this.Configuration.IndeficationByte)
                            {
                                if (this.m_listconnections.TryGetValue(packet.Addres, out _) == false)
                                {
                                    if (this is NetworkServer)
                                    {
                                        this.BaseSocket.Client.SendTo(new byte[] { 253, 253, 253, 253, this.Configuration.IndeficationByte }, packet.Addres);
                                    }

                                    this.m_listconnections[packet.Addres] = new NetworkConnection(this, packet.Addres);
                                    OnConnected?.Invoke(this.m_listconnections[packet.Addres]);
                                }

                                NetworkReceivedPacket.SetPoolObject(packet);
                                continue;
                            }

                            break;

                        case 252:
                            if (packet.Buffer[1] == 252 && packet.Buffer.Length > 3 && packet.Buffer[2] == 252 && packet.Buffer[3] == 252)
                            {
                                if (this.m_listconnections.TryGetValue(packet.Addres, out var connection))
                                {
                                    connection.OnUpdateResponseTime();
                                }

                                NetworkReceivedPacket.SetPoolObject(packet);
                                continue;
                            }

                            break;
                        }

                        if (this.Configuration.Cryptor != null)
                        {
                            packet.Buffer = this.Configuration.Cryptor.Decryption(packet.Buffer);
                        }

                        if (packet.Buffer[0] == this.Configuration.IndeficationByte && this.m_listconnections.TryGetValue(packet.Addres, out NetworkConnection connection_end) && this.m_listconnections[packet.Addres].IsConnected)
                        {
                            this.Read.Buffer = packet.Buffer;
                            OnMessage?.Invoke(connection_end);
                        }
                    }
                    NetworkReceivedPacket.SetPoolObject(packet);
                }

                if (this.m_listconnections.Count != 0)
                {
                    int thisTime = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
                    foreach (var connection in this.m_listconnections)
                    {
                        if (thisTime - connection.Value.LastResponseTime >= this.Configuration.TimeOut)
                        {
                            this.KickConnection(connection.Value, "Time Out!");
                        }
                        else if ((int)thisTime != (int)connection.Value.LastRequestTime)
                        {
                            this.BaseSocket.Client.SendTo(new byte[] { 252, 252, 252, 252 }, connection.Key);
                            connection.Value.OnUpdateRequestTime();
                        }
                    }

                    if (this.m_listdisconnected.Count != 0)
                    {
                        if (this is NetworkServer)
                        {
                            foreach (var connection in this.m_listdisconnected)
                            {
                                if (this.m_listconnections.TryGetValue(connection.Key.Addres, out _))
                                {
                                    this.m_listconnections.Remove(connection.Key.Addres);
                                }

                                List <Byte> disconnectBytes = new List <byte>()
                                {
                                    254, 254, 254, 254
                                };
                                disconnectBytes.AddRange(Encoding.ASCII.GetBytes(connection.Value));

                                this.BaseSocket.Client.SendTo(disconnectBytes.ToArray(), connection.Key.Addres);

                                if (this.m_listfragmentsPerConnection.TryGetValue(connection.Key.Addres, out var ms))
                                {
                                    ms.Dispose();
                                    this.m_listfragmentsPerConnection.Remove(connection.Key.Addres);
                                }

                                OnDisconnected?.Invoke(connection.Key, connection.Value);
                            }
                        }
                        else
                        {
                            (this as NetworkClient).Disconnect(this.m_listdisconnected.First().Value);
                        }
                        this.m_listdisconnected.Clear();
                    }
                }
            }
        }
 public static void SetPoolObject(NetworkReceivedPacket obj)
 {
     ListPoolObjects.Enqueue(obj);
 }