Esempio n. 1
0
 /// <summary> Detects acknowledged and lost messages. </summary>
 private void AckDelivered(NetHeader header)
 {
     for (int i = 0; i < sendWindow.Count; i++)
     {
         int seqDist = NetMath.SeqDistance(sendWindow[i], header.AckSequence);
         // This AckSequence is older than the sendWindow's, not useful:
         if (seqDist > 0)
         {
             break;
         }
         // AckHistory has rolled over without acking this message; Ordered reliable is broken:
         if (seqDist <= -64)
         {
             Connection.Disconnect();
         }
         // If the seqDistance corresponds to a true bit in the AckHistory, message delivered/acked:
         else if (IsAcked(header.AckHistory, seqDist))
         {
             MessageDelivered(i, header);
             i--; // Since the sendWindow count will decrease, the index needs to be adjusted.
         }
         // The seqDist is still within the send window, but if too much time has passed, assume lost:
         else if (NetTime.Milliseconds() - sendWindowTime[i] > 333)
         {
             MessageLost(i);
         }
     }
 }
Esempio n. 2
0
        /// <summary> Handles a stream based on its header/size. Determines if it should be buffered if out-of-order,
        /// acked and released if size is equal to header size (ack only), or delivered immediately. </summary>
        internal void RouteIncomingStream(NetStream strm)
        {
            var header  = NetHeader.FromStream(strm);
            int seqDist = NetMath.SeqDistance(header.ObjSequence, LastAcceptedRemoteSequence);

            // If the stream is only the size of a header, it's likely a forced ack:
            if (strm.Length <= 120)
            {
                AckDelivered(header);
                strm.Release();
            }
            else if (!RemoteSequenceValid(seqDist))
            {
                strm.Release();
            }
            else if (seqDist != 1)
            {
                BufferOutOfOrder(seqDist, strm, header);
            }
            else
            {
                AckReceived(header);
                AckDelivered(header);
                DeliverStream(strm);
            }
        }
Esempio n. 3
0
        /// <summary> Acknowledges and updates the remote sequence. </summary>
        private void AckReceived(NetHeader header)
        {
            int newestDist = NetMath.SeqDistance(header.ObjSequence, NewestRemoteSequence);

            // If the sequence is newest, shift the buffer and apply ack bit:
            if (newestDist > 0)
            {
                AckHistory           = (AckHistory << newestDist) | 1UL;
                NewestRemoteSequence = header.ObjSequence;
            }
            // Else, shift the ack bit and apply to buffer:
            else
            {
                AckHistory |= 1UL << -newestDist;
            }

            LastReceiveTime = NetTime.Milliseconds();

            ReceivedSinceLastSend++;
            Received++;
        }