Ejemplo n.º 1
0
 /// <summary>
 /// Called when a packet has been determined as lost
 /// </summary>
 /// <param name="Packet">The packet that was lost</param>
 private void PacketLost(GMPacket Packet)
 {
     if (!Packet.IgnoreLoss) // Only resend if needed
     {
         Send(Packet);
     }
 }
Ejemplo n.º 2
0
 /// <summary>
 /// The <see cref="Socket"/> send callback
 /// </summary>
 /// <param name="AR"></param>
 private void OnSendTo(IAsyncResult AR)
 {
     try
     {
         int Sent = _Socket.EndSendTo(AR);
         if (_Connected)
         {
             GMPacket InQueue = _SendQueue.TakeFirst();
             if (InQueue != null)
             {
                 Send(InQueue, true);
             }
             else
             {
                 _Sending = false;
             }
         }
         else
         {
             _Socket.Close();
             _Socket.Dispose();
             _Socket = null;
         }
     }
     catch (Exception E)
     {
         Logger.Log(E, true);
         Dispose("Networking Error, 0x01");
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Sends a packet to the set <see cref="EndPoint"/>
        /// </summary>
        /// <param name="Packet">The <see cref="GMPacket"/> to send</param>
        /// <param name="Bypass">Should this send bypass the <see cref="_Sending"/> variable</param>
        public void Send(GMPacket Packet, bool Bypass = false)
        {
            if (!_Connected && Packet.Type != GMPacketType.Disconnect)
            {
                return;
            }

            if (_Sending && !Bypass)
            {
                _SendQueue.Add(Packet);
                return;
            }
            _Sending = true;

            Packet.SequenceId  = _LocalSequence++;
            Packet.SequenceAck = _RemoteSequence;
            Packet.AckBitfield = CreateAckBitfield();

            _SentPackets.TryAdd(Packet.SequenceId, new Tuple <GMPacket, DateTime>(Packet, DateTime.Now));

            Tuple <GMPacket, DateTime> Out;

            if (_SentPackets.TryRemove((ushort)(Packet.SequenceId - Sent_Packet_Queue_Length), out Out))
            {
                PacketLost(Out.Item1);
            }

            byte[] Bytes = Packet.GetData();
            _Socket.BeginSendTo(Bytes, 0, Bytes.Length, SocketFlags.None, _RemoteEndPoint, OnSendTo, Packet);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// The receive callback
        /// </summary>
        /// <param name="AR"></param>
        private void OnReceiveFrom(IAsyncResult AR)
        {
            if (_Connected)
            {
                try
                {
                    //EndPoint ClientEP = new IPEndPoint(IPAddress.Any, 0);
                    int Length = _Socket.EndReceiveFrom(AR, ref _RemoteEndPoint);

                    _ReceiveTimeout = DateTime.Now;
                    _HasReceived    = true;

                    if (Length <= 0)
                    {
                        Dispose("Networking Error, 0x03");
                    }
                    else
                    {
                        byte[] Data = new byte[Length];
                        Array.Copy(_ReceiveBuffer, Data, Length);
                        ReceivedPacket(GMPacket.Create(Data));

                        BeginReceive();
                    }
                }
                catch (Exception E) // Disconnected
                {
                    Logger.Log(E, true);
                    Dispose("Networking Error, 0x04");
                }
            }
        }
Ejemplo n.º 5
0
 private void OnReceivePacket(GMPacket Packet)
 {
     if (Packet.Type == GMPacketType.Connect)
     {
         if (!Done)
         {
             Done = true;
             GMConnectPacket Connect = (GMConnectPacket)Packet;
             _OnConnect?.Invoke(Connect.Port);
         }
     }
     else if (!Done)
     {
         Done = true;
         _OnConnect?.Invoke(0);
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Called when a <see cref="GMPacket"/> is received from the remote client
        /// </summary>
        /// <param name="Packet">The <see cref="GMPacket"/> received</param>
        private void ReceivedPacket(GMPacket Packet)
        {
            try
            {
                int SeqDif = SequenceDifference(_RemoteSequence, Packet.SequenceId);
                if (SeqDif > 0) // If the packet is newer
                {
                    _RemoteSequence = Packet.SequenceId;
                    Array.Copy(_RemoteReceived, 0, _RemoteReceived, SeqDif, _RemoteReceived.Length - SeqDif); // Shift Array
                    _RemoteReceived[0] = true;

                    for (int i = 1; i < SeqDif; i++) // Reset the unshifted elements if the SeqDif is > 1
                    {
                        _RemoteReceived[i] = false;
                    }
                }
                else if (SeqDif < 0 && SeqDif > -(_RemoteReceived.Length - 1)) // An older packet, if the sequence is out of the receive array, drop it
                {
                    _RemoteReceived[Math.Abs(SeqDif)] = true;
                }

                ParseAcknowledegment(Packet.SequenceAck, Packet.AckBitfield);

                if (Packet.Type == GMPacketType.Ping)
                {
                    Send(new GMPongPacket
                    {
                        PingId = ((GMPingPacket)Packet).PingId
                    });
                }

                OnReceivedPacket?.Invoke(Packet);
            }
            catch (Exception E)
            {
                Logger.Log(E, true);
                Dispose("Networking Error, 0x02");
            }
        }