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)); } }
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; } }
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(); } } } } } }
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); }