public ReliableChannel(NetPeer peer, bool ordered) { _windowSize = NetConstants.DefaultWindowSize; _peer = peer; _ordered = ordered; _outgoingPackets = new Queue <NetPacket>(_windowSize); _pendingPackets = new PendingPacket[_windowSize]; for (int i = 0; i < _pendingPackets.Length; i++) { _pendingPackets[i] = new PendingPacket(); } if (_ordered) { _receivedPackets = new NetPacket[_windowSize]; } else { _earlyReceived = new bool[_windowSize]; } _localWindowStart = 0; _localSeqence = 0; _remoteSequence = 0; _remoteWindowStart = 0; //Init acks packet int bytesCount = (_windowSize - 1) / BitsInByte + 1; PacketProperty property = _ordered ? PacketProperty.AckReliableOrdered : PacketProperty.AckReliable; _outgoingAcks = _peer.GetPacketFromPool(property, bytesCount); }
public void SendNextPackets() { //Monitor.Enter(_pendingPackets); //get packets from queue //Monitor.Enter(_outgoingPackets); while (_outgoingPackets.Empty == false) { if (_headPendingPacket.Next != _tailPendingPacket) { NetPacket packet = _outgoingPackets.Dequeue(); PendingPacket pendingPacket = _headPendingPacket; pendingPacket.Packet = packet; _localSequence = (_localSequence + 1); // % NetConstants.MaxSequence; if (_localSequence == NetConstants.MaxSequence) { _localSequence = 0; } pendingPacket.Packet.Sequence = (ushort)_localSequence; _headPendingPacket = _headPendingPacket.Next; } else //Queue filled { break; } } //_outgoingPackets.RemoveRange(0, packetUsed); //Monitor.Exit(_outgoingPackets); ResendPackets(); }
public virtual PendingPacket QueueIncomingPacket(EndPoint endPoint, Packet packet) { var pendingPacket = PendingPacket.FromPacket(endPoint, packet); incoming.Enqueue(pendingPacket); return(pendingPacket); }
public override void SendNextPackets() { //check sending acks if (_mustSendAcks) { _mustSendAcks = false; NetUtils.DebugWrite("[RR]SendAcks"); Monitor.Enter(_outgoingAcks); Peer.SendRawData(_outgoingAcks); Monitor.Exit(_outgoingAcks); } long currentTime = DateTime.UtcNow.Ticks; Monitor.Enter(_pendingPackets); //get packets from queue Monitor.Enter(OutgoingQueue); while (OutgoingQueue.Count > 0) { int relate = NetUtils.RelativeSequenceNumber(_localSeqence, _localWindowStart); if (relate < _windowSize) { PendingPacket pendingPacket = _pendingPackets[_localSeqence % _windowSize]; pendingPacket.Sended = false; pendingPacket.Packet = OutgoingQueue.Dequeue(); pendingPacket.Packet.Sequence = (ushort)_localSeqence; _localSeqence = (_localSeqence + 1) % NetConstants.MaxSequence; } else //Queue filled { break; } } Monitor.Exit(OutgoingQueue); //send double resendDelay = Peer.ResendDelay; for (int pendingSeq = _localWindowStart; pendingSeq != _localSeqence; pendingSeq = (pendingSeq + 1) % NetConstants.MaxSequence) { PendingPacket currentPacket = _pendingPackets[pendingSeq % _windowSize]; if (currentPacket.Packet == null) { continue; } if (currentPacket.Sended) //check send time { double packetHoldTime = currentTime - currentPacket.TimeStamp; if (packetHoldTime < resendDelay * TimeSpan.TicksPerMillisecond) { continue; } NetUtils.DebugWrite("[RC]Resend: {0} > {1}", (int)packetHoldTime, resendDelay); } currentPacket.TimeStamp = currentTime; currentPacket.Sended = true; Peer.SendRawData(currentPacket.Packet); } Monitor.Exit(_pendingPackets); }
PendingPacket ExpirePendingPacket(int time) { byte id = 0; PendingPacket packet = new PendingPacket(); lock (m_pendingPackets) { if (m_pendingPackets.Count > 0) { if ((time - m_pendingPackets[0].TimeStamp) > m_timerInterval) { packet = m_pendingPackets[0]; id = packet.Cookie; packet.Cookie = 0; m_pendingPackets.RemoveAt(0); } } } if (id != 0) { lock (m_availableIds) { m_availableIds.Enqueue(id); } } return(packet); }
public ReliableChannel(NetPeer peer, bool ordered, byte id) : base(peer) { _id = id; _windowSize = NetConstants.DefaultWindowSize; _ordered = ordered; _pendingPackets = new PendingPacket[_windowSize]; for (int i = 0; i < _pendingPackets.Length; i++) { _pendingPackets[i] = new PendingPacket(); } if (_ordered) { _deliveryMethod = DeliveryMethod.ReliableOrdered; _receivedPackets = new NetPacket[_windowSize]; } else { _deliveryMethod = DeliveryMethod.ReliableUnordered; _earlyReceived = new bool[_windowSize]; } _localWindowStart = 0; _localSeqence = 0; _remoteSequence = 0; _remoteWindowStart = 0; _outgoingAcks = new NetPacket(PacketProperty.Ack, (_windowSize - 1) / BitsInByte + 2) { ChannelId = id }; }
void TimeoutEvent(object state) { while (true) { PendingPacket packet = ExpirePendingPacket(Environment.TickCount); if (packet.Packet != null) { if (packet.Attempt >= m_retryMax) { m_dispatcher.NotifySendFailure(this, packet.Packet); } else { lock (m_resendPackets) { m_resendPackets.Add(packet); } } } else { break; } } PumpResend(); }
PendingPacket RetirePendingPacket(byte id) { bool found = false; PendingPacket packet = new PendingPacket(); lock (m_pendingPackets) { for (int pInd = 0, count = m_pendingPackets.Count; pInd < count; ++pInd) { if (m_pendingPackets[pInd].Cookie == id) { packet = m_pendingPackets[pInd]; packet.Cookie = 0; m_pendingPackets.RemoveAt(pInd); found = true; break; } } } if (found) { lock (m_availableIds) { m_availableIds.Enqueue(id); } } return(packet); }
public ReliableChannel(NetPeer peer, bool ordered, int windowSize) { _resendDelay = peer.Handler.ReliableResendTime; _windowSize = windowSize; _peer = peer; _ordered = ordered; _outgoingPackets = new Queue<NetPacket>(_windowSize); _outgoingAcks = new bool[_windowSize]; _pendingPackets = new PendingPacket[_windowSize]; for (int i = 0; i < _pendingPackets.Length; i++) { _pendingPackets[i] = new PendingPacket(); } if (_ordered) _receivedPackets = new NetPacket[_windowSize]; else _earlyReceived = new bool[_windowSize]; _localWindowStart = 0; _localSeqence = 0; _remoteSequence = 0; _remoteWindowStart = 0; }
public ReliableChannel(NetPeer peer, bool ordered, int windowSize) { _windowSize = windowSize; _peer = peer; _ordered = ordered; _outgoingPackets = new Queue <NetPacket>(_windowSize); _outgoingAcks = new bool[_windowSize]; _pendingPackets = new PendingPacket[_windowSize]; for (var i = 0; i < _pendingPackets.Length; i++) { _pendingPackets[i] = new PendingPacket(); } if (_ordered) { _receivedPackets = new NetPacket[_windowSize]; } else { _earlyReceived = new bool[_windowSize]; } _localWindowStart = 0; _localSeqence = 0; _remoteSequence = 0; _remoteWindowStart = 0; }
public void EnqueuePacketForProcessing(byte[] rawData, object userData) { #if DEBUG if (SimulateLatency) { lock (delayedPackets) { PendingPacket packet = new PendingPacket(rawData, userData); DateTime dueTime = DateTime.UtcNow.AddMilliseconds(simulationRandom.Next(SimulatedMinLatency, SimulatedMaxLatency)); delayedPackets.Add(new DelayedPacket(packet, dueTime)); } } else { lock (pendingPackets) { pendingPackets.Enqueue(new PendingPacket(rawData, userData)); } } #else lock (pendingPackets) { pendingPackets.Enqueue(new PendingPacket(rawData, userData)); } #endif }
public virtual PendingPacket QueueOutgoingPacket(EndPoint endPoint, Packet packet) { var pendingPacket = PendingPacket.FromPacket(endPoint, packet, incoming: false); outgoing.Enqueue(pendingPacket); return(pendingPacket); }
public ReliableChannel(NetPeer peer, bool ordered, int channel) { _windowSize = NetConstants.DefaultWindowSize; _peer = peer; _ordered = ordered; _channel = channel; _outgoingPackets = new List <NetPacket>(_windowSize); _pendingPackets = new PendingPacket[_windowSize]; for (int i = 0; i < _pendingPackets.Length; i++) { _pendingPackets[i] = new PendingPacket(); _pendingPackets[i].idx = i; } if (_ordered) { _receivedPackets = new NetPacket[_windowSize]; } else { _earlyReceived = new bool[_windowSize]; } _localSequence = 0; _remoteSequence = 0; _packetsToAcknowledge = new List <ushort>(); _mustSendAcksStartTimer = -1; //Init acks packet PacketProperty property = _ordered ? PacketProperty.AckReliableOrdered : PacketProperty.AckReliable; _outgoingAcks = _peer.GetPacketFromPool(property, channel, NetConstants.MinPacketDataSize); }
public void Clear() { Next = null; Packet = null; Sended = false; Resends = 0; }
//ProcessAck in packet public void ProcessAck(NetPacket packet) { ushort ackWindowStart = packet.Sequence; if (ackWindowStart >= NetConstants.MaxSequence) { NetUtils.DebugWrite("[PA]Bad window start"); return; } byte[] acksData = packet.RawData; NetUtils.DebugWrite("[PA]AcksStart: {0}", ackWindowStart); //Monitor.Enter(_pendingPackets); for (int i = 0; i < packet.GetDataSize(); ++i) { byte acksByte = acksData[i]; for (int idx = 0; idx < 8; ++idx) { if ((acksByte & (1 << idx)) == 0) { // Packet not ack, will be resent automaticaly as needed continue; } // packet acknowledged = true int seqAck = NetUtils.IncrementSequenceNumber(ackWindowStart, i * 8 + idx); PendingPacket pendingPacket = _tailPendingPacket; PendingPacket prevPacket = null; while (pendingPacket != _headPendingPacket) { // Looking for the packet to acknowledge if (pendingPacket.Packet == null || pendingPacket.Packet.Sequence != seqAck) { prevPacket = pendingPacket; pendingPacket = pendingPacket.Next; continue; } //clear acked packet pendingPacket.Packet.DontRecycleNow = false; pendingPacket.Packet.Recycle(); pendingPacket.Clear(); // Packet found, remove it from the list while (_tailPendingPacket.Packet == null && _tailPendingPacket != _headPendingPacket) { _tailPendingPacket = _tailPendingPacket.Next; } NetUtils.DebugWrite("[PA]Removing reliableInOrder ack: {0} - true", seqAck); break; } } } packet.Recycle(); //Monitor.Exit(_pendingPackets); }
public void SendNextPackets() { //check sending acks DateTime currentTime = DateTime.UtcNow; Monitor.Enter(_pendingPackets); //get packets from queue Monitor.Enter(_outgoingPackets); while (_outgoingPackets.Count > 0) { int relate = NetUtils.RelativeSequenceNumber(_localSeqence, _localWindowStart); if (relate < _windowSize) { PendingPacket pendingPacket = _pendingPackets[_localSeqence % _windowSize]; pendingPacket.Packet = _outgoingPackets.Dequeue(); pendingPacket.Packet.Sequence = (ushort)_localSeqence; if (_headPendingPacket != null) { _headPendingPacket.Next = pendingPacket; pendingPacket.Prev = _headPendingPacket; } _headPendingPacket = pendingPacket; _localSeqence = (_localSeqence + 1) % NetConstants.MaxSequence; } else //Queue filled { break; } } Monitor.Exit(_outgoingPackets); //if no pending packets return if (_headPendingPacket == null) { Monitor.Exit(_pendingPackets); return; } //send PendingPacket currentPacket = _headPendingPacket; do { if (currentPacket.TimeStamp.HasValue) //check send time { double packetHoldTime = (currentTime - currentPacket.TimeStamp.Value).TotalMilliseconds; if (packetHoldTime < _peer.ResendDelay) { continue; } NetUtils.DebugWrite("[RC]Resend: {0} > {1}", (int)packetHoldTime, _peer.ResendDelay); } currentPacket.TimeStamp = currentTime; _peer.SendRawData(currentPacket.Packet); } while ((currentPacket = currentPacket.Prev) != null); Monitor.Exit(_pendingPackets); }
public bool TryGetNextIncomingPacket(out PendingPacket packet) { packet = null; if (incoming.Count == 0) { return(false); } return(incoming.TryDequeue(out packet)); }
public override PendingPacket QueueIncomingPacket(EndPoint endPoint, Packet packet) { if (QueueOrDiscardPendingPackages(endPoint, PendingPacket.FromPacket(endPoint, packet))) { return(base.QueueIncomingPacket(endPoint, packet)); } Console.WriteLine($"Dropping Packet from {endPoint}. Packet is too old {packet.Sequence} < {sequence}"); return(null); }
protected virtual bool QueueOrDiscardPendingPackages(EndPoint endPoint, PendingPacket packet) { if (CheckSequence(packet.Sequence, remoteSequence)) { remoteSequence = packet.Sequence; return(true); } return(false); }
public bool HandleOutgoingPackage(ushort sequence, PendingPacket pendingPacket) { if (pendingPacket.PacketType != PacketType.Ack) { sent.Add(sequence, pendingPacket); return(true); } return(false); }
public void SendNextPackets() { //Monitor.Enter(_pendingPackets); //get packets from queue Monitor.Enter(_outgoingPackets); int relate = _headPendingPacket == null ? -1 : _headPendingPacket.idx - 1; if (relate < 0) { relate += _windowSize; } PendingPacket tailPendingPacket = _headPendingPacket; while (tailPendingPacket != null && tailPendingPacket.Next != null) { tailPendingPacket = tailPendingPacket.Next; } int packetUsed = 0; int nextPacket = tailPendingPacket == null ? 0 : tailPendingPacket.idx + 1; foreach (NetPacket packet in _outgoingPackets) { if (tailPendingPacket == null || tailPendingPacket.idx == relate) { PendingPacket pendingPacket = _pendingPackets[nextPacket++ % _windowSize]; pendingPacket.Packet = packet; packetUsed++; pendingPacket.Packet.Sequence = (ushort)_localSequence; if (_headPendingPacket == null) { _headPendingPacket = pendingPacket; } if (tailPendingPacket != null) { tailPendingPacket.Next = pendingPacket; } tailPendingPacket = pendingPacket; _localSequence = NetUtils.IncrementSequenceNumber(_localSequence, 1); } else //Queue filled { break; } } _outgoingPackets.RemoveRange(0, packetUsed); Monitor.Exit(_outgoingPackets); ResendPackets(); }
public void ProcessPacketQueue() { lock (pendingPackets) { ProcessDelayedPackets(); while (pendingPackets.Count > 0) { PendingPacket packet = pendingPackets.Dequeue(); ReadPacket(new NetDataReader(packet.Data), packet.UserData); } } }
private ByteArray HandleNewPacket(ByteArray data) { log.Debug("Handling New Packet of size " + data.Length); byte b = data.ReadByte(); if (~(b & 0x80) > 0) { throw new SFSError("Unexpected header byte: " + b + "\n" + DefaultObjectDumpFormatter.HexDump(data)); } PacketHeader header = PacketHeader.FromBinary(b); pendingPacket = new PendingPacket(header); fsm.ApplyTransition(PacketReadTransition.HeaderReceived); return(ResizeByteArray(data, 1, data.Length - 1)); }
public void Clear() { if (Prev != null) { Prev.Next = Next; } if (Next != null) { Next.Prev = Prev; } Prev = null; Next = null; Packet = null; TimeStamp = null; }
/// <summary> /// /// </summary> /// <param name="data"></param> /// <returns></returns> private ByteArray HandleNewPacket(ByteArray data) { log.Debug("Handling New Packet of size " + data.Length); byte headerByte = data.ReadByte(); if (~(headerByte & 0x80) > 0) { throw new Exception(string.Concat("Unexpected header byte: ", headerByte)); } PacketHeader header = PacketHeader.FromBinary(headerByte); pendingPacket = new PendingPacket(header); fsm.ApplyTransition(PacketReadTransition.HeaderReceived); return(ResizeByteArray(data, 1, data.Length - 1)); }
protected override bool QueueOrDiscardPendingPackages(EndPoint endPoint, PendingPacket packet) { foreach (var pending in pendingPackets) { if (pending.Key < RemoteSequence) { Incoming.Enqueue(pending.Value); } } if (!base.QueueOrDiscardPendingPackages(endPoint, packet)) { pendingPackets.Add(packet.Sequence, packet); return(false); } return(true); }
public bool Tick() { PendingPacket firstPacket = null; while (pendingPackets.Count > 0 && firstPacket != pendingPackets.Peek()) { var pendingPacket = pendingPackets.Dequeue(); if (!OutPorts[pendingPacket.Port].ConnectedPortClosed && !OutPorts[pendingPacket.Port].TrySend(pendingPacket.Ip, true)) { if (firstPacket == null) { firstPacket = pendingPacket; } pendingPackets.Enqueue(pendingPacket); } } if ((!DoNotTerminateWhenInputPortsAreClosed && AllUpstreamPortsAreClosed()) || AllDownstreamPortsAreClosed()) { Status = ProcessStatus.Terminated; } if (Status == ProcessStatus.Terminated) { return(false); } if (pendingPackets.Count > 0) { Status = ProcessStatus.Blocked; return(false); } else { var packetWasSentThisTick = false; if (HasInputPacketWaiting) { Status = ProcessStatus.Active; foreach (var kvp in InPorts) { packetWasSentThisTick = kvp.Value.Tick() || packetWasSentThisTick; } } return(Update() || packetWasSentThisTick); } }
public void ResendPackets() { long currentTime = NetTime.NowMs; //if no pending packets return if (_headPendingPacket == null) { //Monitor.Exit(_pendingPackets); SendAcks(false, currentTime); return; } //send long resendDelay = _peer.ResendDelay + _peer.NetManager.AvgUpdateTime; PendingPacket currentPacket = _headPendingPacket; int countPack = 0; do { countPack++; if (countPack > _windowSize) { break; } if (currentPacket.SentCount > 0) //check send time { long packetHoldTime = currentTime - currentPacket.TimeStamp; // In Second if (packetHoldTime < resendDelay * (1 + currentPacket.SentCount * currentPacket.SentCount)) { continue; } NetUtils.DebugWrite("[RC]Resend: {0} > {1}", (int)packetHoldTime, resendDelay); #if STATS_ENABLED || DEBUG _peer.Statistics.PacketLoss++; #endif } currentPacket.TimeStamp = currentTime; currentPacket.SentCount++; SendAcks(true, currentTime); _peer.SendRawData(currentPacket.Packet); }while ((currentPacket = currentPacket.Next) != null); //Monitor.Exit(_pendingPackets); SendAcks(false, currentTime); }
public NetPacket GetAndClear() { if (Prev != null) { Prev.Next = Next; Prev = null; } if (Next != null) { Next.Prev = Prev; Next = null; } var packet = Packet; Packet = null; TimeStamp = null; return(packet); }
public override PendingPacket QueueIncomingPacket(EndPoint endPoint, Packet packet) { PendingPacket pendingPacket = base.QueueIncomingPacket(endPoint, packet); foreach (var pending in pendingPackets) { if (!base.QueueOrDiscardPendingPackages(pending.Value.RemoteEndPoint, pending.Value)) { break; } Incoming.Enqueue(pending.Value); } long now = DateTime.Now.Ticks; for (int i = pendingPackets.Count - 1; i >= 0; i--) { if (pendingPackets.Keys[i] < RemoteSequence || (now - pendingPackets.Values[0].Sent > PacketExpire.Ticks)) { pendingPackets.RemoveAt(i); } } return(pendingPacket); }
private ByteArray HandleNewPacket(ByteArray data) { this.log.Debug(new string[] { "Handling New Packet of size " + data.Length }); byte b = data.ReadByte(); if (~(b & 128) > 0) { throw new AWError(string.Concat(new object[] { "Unexpected header byte: ", b, "\n", DefaultObjectDumpFormatter.HexDump(data) })); } PacketHeader header = PacketHeader.FromBinary((int)b); this.pendingPacket = new PendingPacket(header); this.fsm.ApplyTransition(PacketReadTransition.HeaderReceived); return(this.ResizeByteArray(data, 1, data.Length - 1)); }