public static uint GetAckMask(IncomingUDPPacketsHolder IncomingHolder, uint AckMask) { AckMask <<= 1; ushort bitCount = Constants.UDP.ACK_MASK_SIZE * 8; for (ushort i = 0; i < bitCount; ++i) { ushort offset = (ushort)(i + 1); if (offset >= IncomingHolder.LastID) { break; } ulong packetID = IncomingHolder.LastID - offset; IncomingUDPPacket packet = null; IncomingHolder.PacketsMap.TryGetValue(packetID, out packet); if (packet == null || packet.IsCompleted) { AckMask = BitwiseHelper.Enable(AckMask, (ushort)(bitCount - offset)); } } return(AckMask); }
private void ProcessIncomingNonReliablePacket(UDPClient Sender, IncomingUDPPacket Packet) { IncomingUDPPacketsHolder.ProcessNonReliablePacket(Sender.IncomingNonReliablePacketHolder, Packet, (Buffer) => { HandleReceivedBuffer(Sender, Buffer); }); }
private void ProcessIncomingReliablePackets(UDPClient Sender) { IncomingUDPPacketsHolder.ProcessReliablePackets(Sender.IncomingReliablePacketHolder, (Buffer) => { HandleReceivedBuffer(Sender, Buffer); }); }
public UDPClient(IPEndPoint EndPoint) { endPoint = EndPoint; IncomingReliablePacketHolder = new IncomingUDPPacketsHolder(); IncomingNonReliablePacketHolder = new IncomingUDPPacketsHolder(); OutgoingReliablePacketHolder = new OutgoingUDPPacketsHolder(); OutgoingNonReliablePacketHolder = new OutgoingUDPPacketsHolder(); }
public virtual void Send(byte[] Buffer, uint Index, uint Length, bool Reliable = true) { OutgoingUDPPacketsHolder outgoingHolder = (Reliable ? outgoingReliablePacketHolder : outgoingNonReliablePacketHolder); IncomingUDPPacketsHolder incomingHolder = (Reliable ? incomingReliablePacketHolder : incomingNonReliablePacketHolder); OutgoingUDPPacket packet = OutgoingUDPPacket.CreateOutgoingBufferStream(outgoingHolder, incomingHolder, Buffer, Index, Length, MTU, Reliable); SendPacket(packet); }
protected override void ProcessReceivedBuffer(Client Sender, BufferStream Buffer) { ulong lastAckID = Buffer.ReadUInt64(); uint ackMask = Buffer.ReadUInt32(); bool isReliable = Buffer.ReadBool(); ulong packetID = Buffer.ReadUInt64(); ushort sliceCount = Buffer.ReadUInt16(); ushort sliceIndex = Buffer.ReadUInt16(); BufferStream buffer = new BufferStream(Buffer.Buffer, Constants.UDP.PACKET_HEADER_SIZE, Buffer.Size - Constants.UDP.PACKET_HEADER_SIZE); UDPClient client = (UDPClient)Sender; IncomingUDPPacketsHolder incomingHolder = (isReliable ? client.IncomingReliablePacketHolder : client.IncomingNonReliablePacketHolder); IncomingUDPPacket packet = incomingHolder.GetPacket(packetID); if (packet == null) { packet = new IncomingUDPPacket(packetID, sliceCount); incomingHolder.AddPacket(packet); } packet.SetSliceBuffer(sliceIndex, buffer); if (packet.IsCompleted) { if (incomingHolder.LastID < packet.ID) { incomingHolder.SetLastID(packet.ID); } if (isReliable) { ProcessIncomingReliablePackets(client); } else { ProcessIncomingNonReliablePacket(client, packet); } } OutgoingUDPPacketsHolder outgoingHolder = (isReliable ? client.OutgoingReliablePacketHolder : client.OutgoingNonReliablePacketHolder); outgoingHolder.SetLastAckID(lastAckID); outgoingHolder.SetAckMask(ackMask); if (isReliable) { ProcessOutgoingReliablePackets(client); } else { ProcessOutgoingNonReliablePackets(client); } }
public UDPClientSocket() : base(Protocols.UDP) { incomingReliablePacketHolder = new IncomingUDPPacketsHolder(); incomingNonReliablePacketHolder = new IncomingUDPPacketsHolder(); outgoingReliablePacketHolder = new OutgoingUDPPacketsHolder(); outgoingNonReliablePacketHolder = new OutgoingUDPPacketsHolder(); FindOptimumMTU = true; MTU = Constants.UDP.MAX_MTU; }
public virtual void Send(Client Target, byte[] Buffer, uint Index, uint Length, bool Reliable = true) { UDPClient client = (UDPClient)Target; OutgoingUDPPacketsHolder outgoingHolder = (Reliable ? client.OutgoingReliablePacketHolder : client.OutgoingNonReliablePacketHolder); IncomingUDPPacketsHolder incomingHolder = (Reliable ? client.IncomingReliablePacketHolder : client.IncomingNonReliablePacketHolder); OutgoingUDPPacket packet = OutgoingUDPPacket.CreateOutgoingBufferStream(outgoingHolder, incomingHolder, Buffer, Index, Length, client.MTU, Reliable); SendPacket(Target, packet); }
public static BufferStream CreatePingBufferStream(OutgoingUDPPacketsHolder ReliableOutgoingHolder, IncomingUDPPacketsHolder ReliableIncomingHolder, OutgoingUDPPacketsHolder NonReliableOutgoingHolder, IncomingUDPPacketsHolder NonReliableIncomingHolder) { BufferStream buffer = Packet.CreatePingBufferStream((Constants.UDP.LAST_ACK_ID_SIZE + Constants.UDP.ACK_MASK_SIZE) * 2); uint ackMask = IncomingUDPPacketsHolder.GetAckMask(ReliableIncomingHolder, ReliableOutgoingHolder.AckMask); buffer.WriteUInt64(ReliableIncomingHolder.LastID); buffer.WriteUInt32(ackMask); ackMask = IncomingUDPPacketsHolder.GetAckMask(NonReliableIncomingHolder, NonReliableOutgoingHolder.AckMask); buffer.WriteUInt64(NonReliableIncomingHolder.LastID); buffer.WriteUInt32(ackMask); return(buffer); }
public static OutgoingUDPPacket CreateOutgoingBufferStream(OutgoingUDPPacketsHolder OutgoingHolder, IncomingUDPPacketsHolder IncomingHolder, byte[] Buffer, uint Index, uint Length, uint MTU, bool IsReliable) { if (Constants.UDP.PACKET_HEADER_SIZE >= MTU) { throw new Exception("PACKET_HEADER_SIZE [" + Constants.UDP.PACKET_HEADER_SIZE + "] is greater than or equal to MTU [" + MTU + "]"); } OutgoingHolder.IncreaseLastID(); ulong id = OutgoingHolder.LastID; uint mtu = MTU - Constants.UDP.PACKET_HEADER_SIZE; ushort sliceCount = (ushort)Math.Ceiling(Length / (float)mtu); OutgoingUDPPacket packet = new OutgoingUDPPacket(id, sliceCount); uint ackMask = IncomingUDPPacketsHolder.GetAckMask(IncomingHolder, OutgoingHolder.AckMask); for (ushort i = 0; i < sliceCount; ++i) { uint index = Index + (i * mtu); uint length = (uint)Math.Min(mtu, Length - (i * mtu)); BufferStream buffer = Packet.CreateOutgoingBufferStream(Constants.UDP.PACKET_HEADER_SIZE + length); buffer.WriteUInt64(IncomingHolder.LastID); buffer.WriteUInt32(ackMask); buffer.WriteBool(IsReliable); buffer.WriteUInt64(id); buffer.WriteUInt16(sliceCount); buffer.WriteUInt16(i); buffer.WriteBytes(Buffer, index, length); packet.SetSliceBuffer(i, buffer); } OutgoingHolder.AddPacket(packet); return(packet); }
public static void ProcessReliablePackets(IncomingUDPPacketsHolder Holder, Action <BufferStream> HandleReceivedBuffer) { List <ulong> completedIDs = new List <ulong>(); var it = Holder.PacketsMap.GetEnumerator(); while (it.MoveNext()) { ulong id = it.Current.Key; IncomingUDPPacket packet = it.Current.Value; if (!packet.IsCompleted) { break; } if (id < Holder.PrevID) { completedIDs.Add(id); continue; } if (id - Holder.PrevID > 1) { break; } HandleReceivedBuffer(packet.Combine()); Holder.SetPrevID(id); completedIDs.Add(id); } for (int i = 0; i < completedIDs.Count; ++i) { Holder.PacketsMap.Remove(completedIDs[i]); } }
public static void ProcessNonReliablePacket(IncomingUDPPacketsHolder Holder, IncomingUDPPacket Packet, Action <BufferStream> HandleReceivedBuffer) { HandleReceivedBuffer(Packet.Combine()); Holder.PacketsMap.Remove(Packet.ID); }
private void ProcessIncomingNonReliablePacket(IncomingUDPPacket Packet) { IncomingUDPPacketsHolder.ProcessNonReliablePacket(incomingNonReliablePacketHolder, Packet, HandleReceivedBuffer); }
private void ProcessIncomingReliablePackets() { IncomingUDPPacketsHolder.ProcessReliablePackets(incomingReliablePacketHolder, HandleReceivedBuffer); }