public void AppendPacket(TimedPacket newPacket) { // Assuming the packet is correct for this stream var payloadData = newPacket.Packet.PayloadData; var payloadLength = payloadData.Length; if (payloadLength == 0) { return; } lock (_packetsInfo) { // An extra validation step here would be verifying that the order of packets is not messed up, i.e packet #3 did not arrive before packet #2. // This approach however does not take into account the client data that change server sequence number, // so we rely on the SharpPcap giving us packets in the correct order var newPacketInfo = new PacketInfo(newPacket, base.Length); lock (this) { var position = base.Position; _packetsInfo.AddLast(newPacketInfo); base.Seek(0, SeekOrigin.End); base.Write(payloadData, 0, payloadLength); base.Position = position; } } }
protected override void OnMessage(MessageEventArgs e) { var jobj = JObject.Parse(e.Data); var packet = new TimedPacket(jobj); Program.LogMsg($"{packet}", Discord.LogSeverity.Debug, ID); if (packet.Id == TimedId.Status) { SendStatus(((DateTimeOffset)DateTime.UtcNow).ToUnixTimeMilliseconds(), true); } else if (Changeable != PlayerSide.None) { if (packet.Id == TimedId.Pause) { Game.Stop(packet.Time.Value); } else if (packet.Id == TimedId.Switch) { Game.Switch(packet.Time.Value); } else if (packet.Id == TimedId.Start) { Game.Start(packet.Time.Value); } } }
public static List <TimedPacket> CreatePacketsFromFileLines(string[] lines, List <Flow> flows) { List <TimedPacket> packets = new List <TimedPacket>(); for (int i = 1; i < lines.Length; i++) { string[] split = lines[i].Split(';'); if (split.Length != 4) { throw new FormatException("Row format is invalid"); } if (string.IsNullOrEmpty(split[0])) { throw new FormatException("Packet Number cannot be empty"); } if (!int.TryParse(split[1], out int size)) { throw new FormatException("packet arrival is not a valid integer number"); } if (size <= 0) { throw new FormatException("packet size cannot be zero or negative value"); } Flow flow = flows.Find(f => f.FlowName == split[2]); if (!flows.Exists(f => f.FlowName == flow.FlowName)) { throw new FormatException("packet flow doesn't exsits"); } if (!int.TryParse(split[3], out int arrival)) { throw new FormatException("packet arrival is not a valid integer number"); } if (arrival <= 0) { throw new FormatException("packet arrival cannot be zero or negative value"); } TimedPacket packet = new TimedPacket() { Number = split[0], Size = size, ArrivalTime = arrival, Flow = flow }; if (packets.Exists(p => p.Number == packet.Number)) { throw new FormatException("packet number already exsits"); } packets.Add(packet); } return(packets); }
// Offset is the offset into the stream where this packet starts public PacketInfo(TimedPacket timedPacket, long offset) { Ack = timedPacket.Packet.AcknowledgmentNumber; Seq = timedPacket.Packet.SequenceNumber; Length = timedPacket.Packet.PayloadData.Length; Offset = offset; Time = timedPacket.Time; }
public void SendStatus(long time, bool includeChange = false) { var jobj = Game.ToJson(); if (includeChange) { jobj["change"] = Changeable != PlayerSide.None; } var pck = new TimedPacket(TimedId.Status, jobj); pck.Time = time; Send(pck.ToString()); }
private void DisplayPacket(TimedPacket timedPacket) { if (timedPacket.Packet.Is <TcpPacket>(out var tcpPacket)) { packetsTable.Invoke((MethodInvoker) delegate { var icon = timedPacket.Sender == SenderEnum.Client ? _iconClientSource : _iconServerSource; var localTime = timedPacket.Time.Date.ToLocalTime().ToString("HH:mm:ss.ffffff"); packetsTable.Rows.Add(icon, _packetIndex++, localTime, tcpPacket.AcknowledgmentNumber, tcpPacket.SequenceNumber, tcpPacket.PayloadData.Length, ""); if (_stickPacketsToBottom) { packetsTable.FirstDisplayedScrollingRowIndex = packetsTable.RowCount - 1; } }); } }
private static List <TimedPacket> CalculatWFQwithSkew(List <Flow> flows, List <TimedPacket> packets) { List <TimedPacket> sentPackets = new List <TimedPacket>(); Dictionary <Flow, Queue <TimedPacket> > arrivedPacketsQueues = new Dictionary <Flow, Queue <TimedPacket> >(); Dictionary <Flow, float> lastCalculatedPackets = new Dictionary <Flow, float>(); int wallClock = 1, sentPacketsCount = 0, waitForPacketTime = 0; float arriavalTime = 1; bool packetIsSent = false; packets.Sort(ComparePacketsByArrivalTimes); foreach (Flow flow in flows) { arrivedPacketsQueues.Add(flow, new Queue <TimedPacket>()); lastCalculatedPackets.Add(flow, 0); } while (sentPacketsCount != packets.Count) { List <TimedPacket> arrivedPackets = packets.FindAll(timedPackets => timedPackets.ArrivalTime == wallClock); List <TimedPacket> packetsInQueues = new List <TimedPacket>(); TimedPacket minPacketInQueues = null; int totalQueueCount = 0; if (arrivedPackets.Count > 0) { foreach (var packet in arrivedPackets) { CalculatePacketsFinishTime(lastCalculatedPackets, packet, arriavalTime); } foreach (TimedPacket packet in arrivedPackets) { lastCalculatedPackets[packet.Flow] = packet.FinishedTime; } } foreach (var packet in arrivedPackets) { arrivedPacketsQueues[packet.Flow].Enqueue(packet); } foreach (var flow in arrivedPacketsQueues.Keys) { if (arrivedPacketsQueues[flow].Count > 0) { packetsInQueues.Add(arrivedPacketsQueues[flow].Peek()); } } if (sentPackets.Count != 0 && waitForPacketTime <= wallClock) { packetIsSent = false; } if (packetsInQueues.Count > 0 && !packetIsSent) { minPacketInQueues = packetsInQueues.Aggregate((currentMinPacket, packet) => currentMinPacket.FinishedTime <= packet.FinishedTime ? currentMinPacket : packet); } if (minPacketInQueues != null && !packetIsSent) { sentPackets.Add(arrivedPacketsQueues[minPacketInQueues.Flow].Dequeue()); sentPacketsCount++; waitForPacketTime = wallClock + minPacketInQueues.Size; packetIsSent = true; } foreach (var flow in arrivedPacketsQueues.Keys) { totalQueueCount += arrivedPacketsQueues[flow].Count; } arriavalTime += (1 / (float)(1 + totalQueueCount)); wallClock++; } return(sentPackets); }
private static int ComparePacketsByArrivalTimes(TimedPacket first, TimedPacket second) { return(first.ArrivalTime.CompareTo(second.ArrivalTime)); }
private static int ComparePacketsByFinishedTime(TimedPacket first, TimedPacket second) { return(first.FinishedTime.CompareTo(second.FinishedTime)); }
private static void CalculatePacketsFinishTime(Dictionary <Flow, float> lastCalculatedPackets, TimedPacket packet, float arrivalTime = 0) { var previusPacketFinishTime = lastCalculatedPackets[packet.Flow]; packet.FinishedTime = Math.Max(arrivalTime, previusPacketFinishTime) + ((packet.Size) / (packet.Flow.FlowWeight)); }
private void OnPacketArrive(TimedPacket timedPacket) { DisplayPacket(timedPacket); }