private bool ProcessFragmentCommand(IncomingCommand command)
        {
            if (command.FragmentsRemaining > 0)
            {
                return(false);
            }

            byte[] array = new byte[command.TotalLength];

            for (long i = command.StartSequenceNumber; i < command.StartSequenceNumber + command.FragmentCount; i++)
            {
                if (!Commands.ContainsKey(i))
                {
                    throw new Exception(string.Format("Failed to found {0} command.", i));
                }

                IncomingCommand current        = Commands[i];
                byte[]          currentPayload = current.GetPayload();

                Buffer.BlockCopy(currentPayload, 0, array, current.FragmentOffset, currentPayload.Length);

                Commands.Remove(current.ReliableSequenceNumber);
            }

            command.SetPayload(array);

            //command.Size = (Int32)(12 * command.FragmentCount + command.TotalLength);
            Channel.IncomingReliableSequenceNumber = (uint)(command.ReliableSequenceNumber + command.FragmentCount - 1);

            return(true);
        }
        public override bool EnqueueIncomingCommand(IncomingCommand command)
        {
            if (command.ReliableSequenceNumber < Channel.IncomingReliableSequenceNumber ||
                command.UnreliableSequenceNumber <= Channel.IncomingUnreliableSequenceNumber ||
                Contains(command.UnreliableSequenceNumber))
            {
                return(false);
            }

            AddCommand(command.UnreliableSequenceNumber, command);

            return(true);
        }
        public override bool TryProcessCommand(out IncomingCommand command)
        {
            if (!Commands.TryGetValue(Channel.IncomingReliableSequenceNumber + 1, out command))
            {
                return(false);
            }

            if (command.Type == CommandType.Fragmented)
            {
                return(ProcessFragmentCommand(command));
            }

            Channel.IncomingReliableSequenceNumber = command.ReliableSequenceNumber;
            return(Commands.Remove(command.ReliableSequenceNumber));
        }
        public override bool EnqueueIncomingCommand(IncomingCommand command)
        {
            if (command.ReliableSequenceNumber <= Channel.IncomingReliableSequenceNumber)
            {
                //Duplicated command, already received command.
                return(false);
            }

            if (Contains(command.ReliableSequenceNumber))
            {
                return(false);
            }

            AddCommand(command.ReliableSequenceNumber, command);

            return(true);
        }
        public override bool TryProcessCommand(out IncomingCommand command)
        {
            command = null;
            Queue <long> removeSequenceNumbers = new Queue <long>();

            if (Commands.Count > 0)
            {
                long lastSequenceNumber = long.MaxValue;

                foreach (var unreliableSequenceNumber in Commands.Keys)
                {
                    IncomingCommand unreliableCommand = Commands[unreliableSequenceNumber];

                    if (IsDroppable(unreliableCommand.ReliableSequenceNumber, unreliableSequenceNumber))
                    {
                        removeSequenceNumbers.Enqueue(unreliableSequenceNumber); //Drop
                    }
                    else if (unreliableSequenceNumber < lastSequenceNumber)
                    {
                        if (unreliableCommand.ReliableSequenceNumber <= Channel.IncomingReliableSequenceNumber)
                        {
                            //마지막 Dispatched reliable command 이후에 전송한 unreliable command 중 제일 작인 seq번호
                            lastSequenceNumber = unreliableSequenceNumber;
                        }
                    }
                }

                //queue에 해당되는 제거
                RemoveCommands(removeSequenceNumbers);

                if (lastSequenceNumber < int.MaxValue)
                {
                    command = Commands[lastSequenceNumber];

                    Commands.Remove(command.UnreliableSequenceNumber);
                    Channel.IncomingUnreliableSequenceNumber = command.UnreliableSequenceNumber;

                    return(true);
                }
            }
            return(false);
        }
        internal OutgoingCommand RemoveSentReliableCommand(IncomingCommand inCommand)
        {
            lock (_sentCommands)
            {
                //채널과 reliableSequenceNumber가 동일한 command를 삭제한다.
                OutgoingCommand command = _sentCommands.Find(o => o != null &&
                                                             o.ReliableSequenceNumber == inCommand.AckReceivedReliableSequenceNumber &&
                                                             o.Channel == inCommand.Channel);

                if (command != null)
                {
                    _sentCommands.Erase(command);

                    if (_sentCommands.Count > 0)
                    {
                        Interlocked.Exchange(ref _resendingTimeout, (int)(_sentCommands[0].SentTime + _sentCommands[0].RoundTripTimeout));
                    }
                }
                return(command);
            }
        }
        public void ReceiveFragmentCommand(IncomingCommand command)
        {
            if (command.ReliableSequenceNumber == command.StartSequenceNumber)
            {
                command.FragmentsRemaining--;
                long num = command.StartSequenceNumber + 1;

                while (command.FragmentsRemaining > 0 && num < command.StartSequenceNumber + command.FragmentCount)
                {
                    if (Contains(num++))
                    {
                        command.FragmentsRemaining--;
                    }
                }
            }
            else
            {
                if (Contains(command.StartSequenceNumber))
                {
                    IncomingCommand remain = this[command.StartSequenceNumber];
                    remain.FragmentsRemaining--;
                }
            }
        }
Esempio n. 8
0
 private static void StartNetworkListener()
 {
     networkListenerThread = new Thread(() =>
     {
         while (networkListenerThreadKeepAlive)
         {
             try
             {
                 IncomingCommand command = ConnectionManager.GetCommand();
                 command.ExecuteCommand();
             }
             catch (Exception e)
             {
                 if (networkListenerThreadKeepAlive)
                 {
                     Logger.LogError("Cauldron", "[Network Listener Thread]" + e.Message);
                 }
             }
         }
     });
     networkListenerThread.Name     = "Network Listener Thread";
     networkListenerThreadKeepAlive = true;
     networkListenerThread.Start();
 }
 public abstract bool EnqueueIncomingCommand(IncomingCommand command);
 public abstract bool TryProcessCommand(out IncomingCommand command);
 protected void AddCommand(long seq, IncomingCommand command)
 {
     _commands.Add(seq, command);
 }
 public OutgoingCommand ReceiveAck(IncomingCommand inCommand)
 {
     return(RemoveSentReliableCommand(inCommand));
 }