public override void ProcessDataPacket(ITcpDataPacket packet)
        {
            if (BasicTcpPacket.CompareSequences((ushort)(_sequenceIn + 1), packet.Sequence) == 0)
            {
                // This is exactly what we were expecting
                _sequenceIn++;
                if (packet.ResendCount > 0)
                {
                    PacketCountReceiveDataResend++;
                }
                else
                {
                    PacketCountReceiveDataFirst++;
                }
                SendAck(packet, true);
                Socket.BufferClientData(packet.Data);
            }
            else if (BasicTcpPacket.CompareSequences((ushort)(_sequenceIn + 1), packet.Sequence) > 0)
            {
                // This is an old packet, don't process (already did that), just send ack
#if (DEBUG)
                Logger.Debug("Got old Data packet, sending ACK, data already processed.");
#endif
                SendAck(packet, false);
            }
            else
            {
#if (DEBUG)
                Logger.Debug("Got unexpected sequence (expected " + _sequenceIn + ") from packet " + packet);
#endif
            }
        }
Exemplo n.º 2
0
        // Received this data packet
        public override void ProcessDataPacket(ITcpDataPacket packet)
        {
            if (!Closed)
            {
                lock (_processDataLock)
                {
                    Stats.DataPacketsReceived++;
                    int compareSequences = BasicTcpPacket.CompareSequences(_nextDataSeqIn, packet.Sequence);
                    if (compareSequences == 0)
                    {
                        Stats.ExpectedDataPacketsReceived++;
                        if (BasicTcpPacket.CompareSequences(packet.Sequence, _highestDataSeqIn) > 0)
                        {
                            _highestDataSeqIn = packet.Sequence;
                        }
                        // This is exactly what we were expecting
                        // pop it in our list
                        ITcpDataPacket currentPacket = _recvWindow[_recvWindowsNextFree] = packet;
                        // Now flush our window until we get to a gap
                        while (_recvWindow[_recvWindowsNextFree] != null)
                        {
                            currentPacket = _recvWindow[_recvWindowsNextFree];
                            // Send Data Upstream (only it not closed)
                            if (!Socket.Closed && !Socket.Closing)
                            {
                                Socket.BufferClientData(currentPacket.Data);
                            }
#if DEBUG
                            else
                            {
                                Logger.Debug("Got a data packet, but not writing to socket, because its closed or closing");
                            }
#endif
                            // clear this space in our window
                            _recvWindow[_recvWindowsNextFree] = null;
                            // increment our pointer to next space
                            _recvWindowsNextFree = (byte)((_recvWindowsNextFree + 1) % WindowSize);
                            // increment our next next expected sequence number
                            _nextDataSeqIn++;
#if DEBUG
                            Logger.Debug("Processed sq=" + currentPacket.Sequence + " upstream, nextDataSeqIn=" +
                                         _nextDataSeqIn + ", recvWindowNextFree=" + _recvWindowsNextFree +
                                         ", highestDataSeqIn=" + _highestDataSeqIn);
#endif
                        }
                        // Send Ack (only when done with sending all the packets we can)
                        SendAck(currentPacket, currentPacket, true);
                        _lastAckedPacket = currentPacket;
                    }
                    else if (compareSequences > 0)
                    {
                        Stats.OldDataPacketsReceived++;
                        if (packet.ResendCount > 0)
                        {
                            Stats.OldDataResendPacketsReceived++;
                        }
                        // This is an old packet, don't process (already did that), just send ack
#if DEBUG
                        Logger.Debug("Got old Data packet (resend=" + packet.ResendCount +
                                     "), sending ACK, data already processed.");
#endif
                        SendAck(packet, _lastAckedPacket, false);
                    }
                    else
                    {
                        Stats.FutureDataPacketsReceived++;
                        // This is an out of sequence packet from the future,
                        // if it fits in our window, we need to save it for future use
                        int differenceInSequences = DifferenceInSequences(_nextDataSeqIn, packet.Sequence);
                        if (differenceInSequences < WindowSize)
                        {
                            // ok we can put it in
                            _recvWindow[(_recvWindowsNextFree + differenceInSequences) % WindowSize] = packet;
                            if (BasicTcpPacket.CompareSequences(packet.Sequence, _highestDataSeqIn) > 0)
                            {
                                _highestDataSeqIn = packet.Sequence;
                            }
#if DEBUG
                            Logger.Debug("Queued sq=" + packet.Sequence + " in window, nextDataSeqIn=" + _nextDataSeqIn +
                                         ", recvWindowNextFree=" + _recvWindowsNextFree + ", highestDataSeqIn=" +
                                         _highestDataSeqIn);
#endif
                            // Now we send an ack for the last in sequence packet we received
                            if (_lastAckedPacket != null)
                            {
                                SendAck(packet, _lastAckedPacket, false);
                                Stats.HoldingAcksSent++;
                            }
                        }
                        else
                        {
#if DEBUG
                            Logger.Debug("Got too far in the future sequence (expected " + _nextDataSeqIn + ") from packet " +
                                         packet + ", dropping");
#endif
                            // Now we send an ack for the last in sequence packet we received
                            if (_lastAckedPacket != null)
                            {
                                SendAck(_lastAckedPacket, _lastAckedPacket, false);
                                Stats.HoldingAcksSent++;
                            }
                        }
                    }
#if DEBUG
                    if (Stats.DataPacketsReceived % 1000 == 0)
                    {
                        Logger.Debug("Received Stats:\n" + Stats.GetReceiverStats());
                    }
#endif

                    Monitor.PulseAll(_processDataLock);
                }
            }
            else
            {
                Logger.Error("Failed to process data packet, the connection closed.");
            }
        }