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.Sent = dtNow;
                lock (sq.Pending)
                    foreach (RUDPPacket unconfirmed in sq.Pending.Where(x => (dtNow - p.Sent).Seconds >= 1))
                    {
                        RetransmitPacket(unconfirmed);
                    }
                Debug("SEND -> {0}: {1}", p.Dst, p);
            }
            else
            {
                Debug("RETRANSMIT -> {0}: {1}", 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));
        }
 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.Received = 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 -> {0}: {1}", 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 <- {0}: {1}", src, ack.sequence);
         lock (sq.Pending)
             sq.Pending.RemoveAll(x => x.Seq == ack.sequence);
     }
     else
     {
         Console.WriteLine("[{0}] RAW RECV: [{1}]", GetType().ToString(), Encoding.ASCII.GetString(data, 0, length));
     }
 }
Exemple #3
0
        private void SendPacket(RUDPPacket p)
        {
            RUDPConnectionData cn = GetConnection(p.Dst);

            if (!p.Retransmit)
            {
                p.Seq = cn.Local;
                cn.Local++;
                p.Sent = DateTime.Now;
                lock (cn.Pending)
                    cn.Pending.Add(p);
                if (p.Type != RUDPPacketType.ACK)
                {
                    lock (cn.Unconfirmed)
                        cn.Unconfirmed.Add(p);
                }
                _sw.SpinOnce();
                Debug("SEND -> {0}: {1}", p.Dst, p);
            }
            else
            {
                Debug("RETRANSMIT -> {0}: {1}", p.Dst, p);
            }
            SendBytes(p.Dst, _serializer.Serialize(PacketHeader, p));
        }
        public void Send(IPEndPoint destination, RUDPPacketType type = RUDPPacketType.DAT, RUDPPacketFlags flags = RUDPPacketFlags.NUL, byte[] data = null, int[] intData = null)
        {
            InitSequence(destination);
            RUDPConnectionData sq = _sequences[destination.ToString()];

            if ((data != null && data.Length < _maxMTU) || data == null)
            {
                SendPacket(new RUDPPacket()
                {
                    Dst   = destination,
                    Id    = sq.PacketId,
                    Type  = type,
                    Flags = flags,
                    Data  = data
                });
                sq.PacketId++;
            }
            else if (data != null && data.Length >= _maxMTU)
            {
                int i = 0;
                List <RUDPPacket> PacketsToSend = new List <RUDPPacket>();
                while (i < data.Length)
                {
                    int min = i;
                    int max = _maxMTU;
                    if ((min + max) > data.Length)
                    {
                        max = data.Length - min;
                    }
                    byte[] buf = data.Skip(i).Take(max).ToArray();
                    PacketsToSend.Add(new RUDPPacket()
                    {
                        Dst   = destination,
                        Id    = sq.PacketId,
                        Type  = type,
                        Flags = flags,
                        Data  = buf
                    });
                    i += _maxMTU;
                }
                foreach (RUDPPacket p in PacketsToSend)
                {
                    p.Qty = PacketsToSend.Count;
                    SendPacket(p);
                }
                sq.PacketId++;
            }
            else
            {
                throw new Exception("This should not happen");
            }
            if (sq.PacketId > PacketIdLimit)
            {
                sq.PacketId = 0;
            }
        }
Exemple #5
0
        public override void PacketReceive(IPEndPoint ep, byte[] data, int length)
        {
            base.PacketReceive(ep, data, length);
            DateTime   dtNow = DateTime.Now;
            IPEndPoint src   = IsServer ? ep : RemoteEndPoint;

            if (length >= PacketHeader.Length && data.Take(PacketHeader.Length).SequenceEqual(PacketHeader))
            {
                RUDPPacket         p  = RUDPPacket.Deserialize(_serializer, PacketHeader, data);
                RUDPConnectionData cn = GetConnection(src);
                cn.LastPacketDate = dtNow;
                p.Src             = src;
                p.Serializer      = _serializer;
                p.Received        = dtNow;
                lock (cn.ReceivedPackets)
                    cn.ReceivedPackets.Add(p);
                SendBytes(p.Src, new RUDPInternalPackets.AckPacket()
                {
                    header = AckPacketHeader, sequence = p.Seq
                }.Serialize());
                //Debug("ACK SEND -> {0}: {1}", p.Src, p.Seq);
                SignalPacketRecv.Set();
            }
            else if (length >= AckPacketHeader.Length && data.Take(AckPacketHeader.Length).SequenceEqual(AckPacketHeader))
            {
                RUDPConnectionData cn = GetConnection(src);
                cn.LastPacketDate = dtNow;
                RUDPInternalPackets.AckPacket ack = RUDPInternalPackets.AckPacket.Deserialize(data);
                //Debug("ACK RECV <- {0}: {1}", src, ack.sequence);
                lock (cn.Pending)
                    cn.Pending.RemoveAll(x => x.Seq == ack.sequence);
            }
            else if (length >= PingPacketHeader.Length && data.Take(PingPacketHeader.Length).SequenceEqual(PingPacketHeader))
            {
                RUDPConnectionData cn = GetConnection(src);
                cn.LastPacketDate = dtNow;
                RUDPInternalPackets.PingPacket ping = RUDPInternalPackets.PingPacket.Deserialize(data);
                Debug("<- PING FROM {0}", src);
            }
            else
            {
                Console.WriteLine("[{0}] RAW RECV: [{1}]", GetType().ToString(), Encoding.ASCII.GetString(data, 0, length));
            }
        }
        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 <- {0}: {1}", 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 {0}", 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 <- {0}: {1}", p.Src, mp);
                                    }
                                buf = ms.ToArray();
                            }
                            Debug("MULTIPACKET ID {0} DATA: {1}", p.Id, Encoding.ASCII.GetString(buf));

                            OnPacketReceived?.Invoke(new RUDPPacket()
                            {
                                ACK        = p.ACK,
                                Retransmit = p.Retransmit,
                                Sent       = p.Sent,
                                Data       = buf,
                                Dst        = p.Dst,
                                Flags      = p.Flags,
                                Id         = p.Id,
                                Qty        = p.Qty,
                                Received   = p.Received,
                                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 ({0} > {1})", p.Qty, multiPackets.Count);
                                throw new Exception();
                            }
                        }
                    }
                }
            }
        }
Exemple #7
0
        private int Send(IPEndPoint destination, RUDPPacketType type = RUDPPacketType.DAT, RUDPPacketFlags flags = RUDPPacketFlags.NUL, byte[] data = null, int[] intData = null, Action <RUDPPacket> OnPacketReceivedByDestination = null)
        {
            if (!_isAlive)
            {
                return(-1);
            }
            RUDPPacket         packet = null;
            bool               reset  = false;
            RUDPConnectionData cn     = GetConnection(destination);

            if ((data != null && data.Length < _maxMTU) || data == null)
            {
                packet = new RUDPPacket()
                {
                    Serializer = _serializer,
                    Dst        = destination,
                    Id         = cn.PacketId,
                    Type       = type,
                    Flags      = flags,
                    Data       = data,
                    intData    = intData,
                    OnPacketReceivedByDestination = OnPacketReceivedByDestination
                };
                SendPacket(packet);
                cn.PacketId++;
                if (!IsServer && cn.Local > SequenceLimit)
                {
                    reset = true;
                }
            }
            else if (data != null && data.Length >= _maxMTU)
            {
                int i = 0;
                List <RUDPPacket> PacketsToSend = new List <RUDPPacket>();
                while (i < data.Length)
                {
                    int min = i;
                    int max = _maxMTU;
                    if ((min + max) > data.Length)
                    {
                        max = data.Length - min;
                    }
                    byte[] buf = data.Skip(i).Take(max).ToArray();
                    PacketsToSend.Add(new RUDPPacket()
                    {
                        Serializer = _serializer,
                        Dst        = destination,
                        Id         = cn.PacketId,
                        Type       = type,
                        Flags      = flags,
                        Data       = buf,
                        intData    = intData
                    });
                    i += _maxMTU;
                }
                foreach (RUDPPacket p in PacketsToSend)
                {
                    p.Qty = PacketsToSend.Count;
                    p.OnPacketReceivedByDestination = OnPacketReceivedByDestination;
                    SendPacket(p);
                }
                cn.PacketId++;
                if (!IsServer && cn.Local > SequenceLimit)
                {
                    reset = true;
                }
                packet = PacketsToSend.First();
            }
            else
            {
                throw new Exception("This should not happen");
            }
            if (cn.PacketId > PacketIdLimit)
            {
                cn.PacketId = 0;
            }
            if (reset)
            {
                SendPacket(new RUDPPacket()
                {
                    Serializer = _serializer,
                    Dst        = destination,
                    Type       = RUDPPacketType.RST
                });
                cn.Local = IsServer ? ServerStartSequence : ClientStartSequence;
            }
            return(packet.Id);
        }