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); }
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(); } } } } } }
// ############################################################################################################################### // ############################################################################################################################### // ############################################################################################################################### private void RetransmitPacket(UDPPacket p) { p.Retransmit = true; SendPacket(p); }
// ############################################################################################################################### // ############################################################################################################################### // ############################################################################################################################### private bool InitSequence(UDPPacket p) { return(InitSequence(p.Src == null ? p.Dst : p.Src)); }