Example #1
0
        private void SendPacket(RUDPPacket p)
        {
            DateTime dtNow = DateTime.Now;

            InitSequence(p.Dst);
            RUDPConnectionData sq = _sequences[p.Dst.ToString()];

            if (!p.Retransmit)
            {
                p.Seq = sq.Local;
                sq.Local++;
                p.Snt_TS = dtNow;
                lock (sq.Pending)
                    foreach (RUDPPacket unconfirmed in sq.Pending.Where(x => (dtNow - p.Snt_TS).Seconds >= 1))
                    {
                        RetransmitPacket(unconfirmed);
                    }
                Debug($"SEND -> { p.Dst}: {p}");
            }
            else
            {
                Debug($"RETRANSMIT -> {p.Dst}: {p}");
            }

            lock (sq.Pending)
            {
                sq.Pending.RemoveAll(x => x.Dst.ToString() == p.Dst.ToString() && x.Seq == p.Seq);
                sq.Pending.Add(p);
            }

            Send(p.Dst, p.ToByteArray(_packetHeader));
        }
Example #2
0
 public override void PacketReceive(IPEndPoint ep, byte[] data, int length)
 {
     base.PacketReceive(ep, data, length);
     if (length > _packetHeader.Length && data.Take(_packetHeader.Length).SequenceEqual(_packetHeader))
     {
         RUDPPacket p = RUDPPacket.Deserialize(_packetHeader, data);
         p.Src    = IsServer ? ep : RemoteEndPoint;
         p.Rcv_TS = DateTime.Now;
         InitSequence(p.Src);
         RUDPConnectionData sq = _sequences[p.Src.ToString()];
         Send(p.Src, new RUDPInternalPacket.ACKPacket()
         {
             header = _internalHeader, sequence = p.Seq
         }.Serialize());
         Debug($"ACK SEND -> {p.Src}: {p.Seq}");
         lock (sq.ReceivedPackets)
             sq.ReceivedPackets.Add(p);
     }
     else if (length > _internalHeader.Length && data.Take(_internalHeader.Length).SequenceEqual(_internalHeader))
     {
         IPEndPoint src = IsServer ? ep : RemoteEndPoint;
         InitSequence(src);
         RUDPConnectionData           sq  = _sequences[src.ToString()];
         RUDPInternalPacket.ACKPacket ack = RUDPInternalPacket.ACKPacket.Deserialize(data);
         Debug($"ACK RECV <- {src}: {ack.sequence}");
         lock (sq.Pending)
             sq.Pending.RemoveAll(x => x.Seq == ack.sequence);
     }
     else
     {
         Console.WriteLine($"[{GetType()}] RAW RECV: [{Encoding.ASCII.GetString(data, 0, length)}]");
     }
 }
Example #3
0
        //public int[] ACK { get; set; }
        public static RUDPPacket Deserialize(byte[] header, byte[] data)
        {
            var buffer     = data.Skip(header.Length).ToArray();
            var rudpPacket = new RUDPPacket();

            rudpPacket.Seq   = BitConverter.ToInt32(buffer, 0);
            rudpPacket.Id    = BitConverter.ToInt32(buffer, 4);
            rudpPacket.Qty   = BitConverter.ToInt32(buffer, 8);
            rudpPacket.Type  = (RUDPPacketType)buffer[13];
            rudpPacket.Flags = (RUDPPacketFlags)buffer[14];
            Array.Copy(buffer, 14, rudpPacket.Data, 0, data.Length - 14);
            return(rudpPacket);
        }
Example #4
0
        public void ProcessRecvQueue()
        {
            foreach (var cdata in _sequences)
            {
                RUDPConnectionData sq = cdata.Value;

                List <RUDPPacket> PacketsToRecv = new List <RUDPPacket>();
                lock (sq.ReceivedPackets)
                    PacketsToRecv.AddRange(sq.ReceivedPackets.OrderBy(x => x.Seq));
                PacketsToRecv = PacketsToRecv.GroupBy(x => x.Seq).Select(g => g.First()).ToList();

                for (int i = 0; i < PacketsToRecv.Count; i++)
                {
                    RUDPPacket p = PacketsToRecv[i];

                    lock (sq.ReceivedPackets)
                        sq.ReceivedPackets.Remove(p);

                    if (p.Seq < sq.Remote)
                    {
                        continue;
                    }

                    if (p.Seq > sq.Remote)
                    {
                        sq.ReceivedPackets.Add(p);
                        break;
                    }

                    Debug($"RECV <- {p.Src}: {p}");

                    if (p.Qty == 0)
                    {
                        sq.Remote++;

                        if (p.Type == RUDPPacketType.SYN)
                        {
                            if (IsServer)
                            {
                                Send(p.Src, RUDPPacketType.SYN, RUDPPacketFlags.ACK);
                                OnClientConnect?.Invoke(p.Src);
                            }
                            else if (p.Flags == RUDPPacketFlags.ACK)
                            {
                                State = ConnectionState.OPEN;
                                OnConnected?.Invoke(p.Src);
                            }
                            continue;
                        }

                        OnPacketReceived?.Invoke(p);
                    }
                    else
                    {
                        // Multipacket!
                        List <RUDPPacket> multiPackets = PacketsToRecv.Skip(i).Take(p.Qty).ToList();
                        if (multiPackets.Count == p.Qty)
                        {
                            Debug($"MULTIPACKET {p.Id}");

                            byte[] buf;
                            using (MemoryStream ms = new MemoryStream())
                            {
                                using (BinaryWriter bw = new BinaryWriter(ms))
                                    foreach (RUDPPacket mp in multiPackets)
                                    {
                                        bw.Write(mp.Data);
                                        Debug($"RECV MP <- {p.Src}: {mp}");
                                    }
                                buf = ms.ToArray();
                            }
                            Debug($"MULTIPACKET ID {p.Id} DATA: {Encoding.ASCII.GetString(buf)}");

                            OnPacketReceived?.Invoke(new RUDPPacket()
                            {
                                //ACK = p.ACK,
                                Retransmit = p.Retransmit,
                                Snt_TS     = p.Snt_TS,
                                Data       = buf,
                                Dst        = p.Dst,
                                Flags      = p.Flags,
                                Id         = p.Id,
                                Qty        = p.Qty,
                                Rcv_TS     = p.Rcv_TS,
                                Seq        = p.Seq,
                                Src        = p.Src,
                                Type       = p.Type
                            });

                            sq.Remote += p.Qty;
                            i         += p.Qty;
                        }
                        else
                        {
                            if (multiPackets.Count < p.Qty)
                            {
                                sq.ReceivedPackets.Add(p);
                                break;
                            }
                            else
                            {
                                Debug($"P.QTY > MULTIPACKETS.COUNT ({p.Qty} > {multiPackets.Count})");
                                throw new Exception();
                            }
                        }
                    }
                }
            }
        }
Example #5
0
        // ###############################################################################################################################
        // ###############################################################################################################################
        // ###############################################################################################################################

        private void RetransmitPacket(RUDPPacket p)
        {
            p.Retransmit = true;
            SendPacket(p);
        }
Example #6
0
        // ###############################################################################################################################
        // ###############################################################################################################################
        // ###############################################################################################################################

        private bool InitSequence(RUDPPacket p)
        {
            return(InitSequence(p.Src == null ? p.Dst : p.Src));
        }