Example #1
0
        protected override bool DecodeReceive(byte[] buffer, int offset, int count, EndPoint ep, out int error)
        {
            error = 0;
            byte[] data = new byte[count];
            Buffer.BlockCopy(buffer, offset, data, 0, count);
            if (count > _packetHeader.Length && data.Take(_packetHeader.Length).SequenceEqual(_packetHeader))
            {
                UDPPacket p = UDPPacket.Deserialize(_packetHeader, data);
                p.Src      = IsServer ? ep : remoterPoint;
                p.Received = DateTime.Now;
                InitSequence(p.Src);
                UDPConnectionData sq = _sequences[p.Src.ToString()];
                SendToAsync(p.Src, new UDPInternalPacket.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 (count > _internalHeader.Length && data.Take(_internalHeader.Length).SequenceEqual(_internalHeader))
            {
                EndPoint src = IsServer ? ep : remoterPoint;
                InitSequence(src);
                UDPConnectionData           sq  = _sequences[src.ToString()];
                UDPInternalPacket.ACKPacket ack = UDPInternalPacket.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, count));
            }

            return(true);
        }
Example #2
0
        public void ProcessRecvQueue()
        {
            foreach (var cdata in _sequences)
            {
                UDPConnectionData sq = cdata.Value;

                List <UDPPacket> PacketsToRecv = new List <UDPPacket>();
                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++)
                {
                    UDPPacket 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 == UDPPacketType.SYN)
                        {
                            if (IsServer)
                            {
                                Send(p.Src, UDPPacketType.SYN, UDPPacketFlags.ACK);
                                OnClientConnect?.Invoke(p.Src);
                            }
                            else if (p.Flags == UDPPacketFlags.ACK)
                            {
                                State = UDPConnectionState.OPEN;
                                OnConnected?.Invoke(p.Src);
                            }
                            continue;
                        }

                        OnPacketReceived?.Invoke(p);
                    }
                    else
                    {
                        // Multipacket!
                        List <UDPPacket> 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 (UDPPacket 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 UDPPacket()
                            {
                                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();
                            }
                        }
                    }
                }
            }
        }
Example #3
0
        // ###############################################################################################################################
        // ###############################################################################################################################
        // ###############################################################################################################################

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

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