Beispiel #1
0
        protected override void AckChunks(int ack)
        {
            do
            {
                if (ResendQueue.Count == 0)
                {
                    return;
                }

                if (ResendQueue.TryPeek(out var chunk))
                {
                    if (NetworkCore.IsSeqInBackroom(chunk.Sequence, ack))
                    {
                        ResendQueue.Dequeue();
                        BufferSize -= SIZEOF_NETWORK_CHUNK_RESEND + chunk.DataSize;
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    return;
                }
            } while (true);
        }
Beispiel #2
0
        public override void Update()
        {
            if (State == ConnectionState.OFFLINE ||
                State == ConnectionState.ERROR)
            {
                return;
            }

            if (State != ConnectionState.OFFLINE &&
                State != ConnectionState.CONNECT &&
                (Time.Get() - LastReceiveTime) > Time.Freq() * Config["ConnTimeout"])
            {
                State = ConnectionState.ERROR;
                Error = "Timeout";
                return;
            }

            if (ResendQueue.Count > 0)
            {
                var resend = ResendQueue.Peek();
                if (Time.Get() - resend.FirstSendTime > Time.Freq() * Config["ConnTimeout"])
                {
                    State = ConnectionState.ERROR;
                    Error = $"Too weak connection (not acked for {Config["ConnTimeout"]} seconds)";
                }
                else if (Time.Get() - resend.LastSendTime > Time.Freq())
                {
                    ResendChunk(resend);
                }
            }

            if (State == ConnectionState.ONLINE)
            {
                if (Time.Get() - LastSendTime > Time.Freq() / 2)
                {
                    var flushedChunks = Flush();
                    if (flushedChunks != 0)
                    {
                        Debug.Log("connection", $"flushed connection due to timeout. {flushedChunks} chunks.");
                    }
                }

                if (Time.Get() - LastSendTime > Time.Freq())
                {
                    SendControlMsg(ConnectionMessages.KEEPALIVE, "");
                }
            }
            else if (State == ConnectionState.CONNECT)
            {
                if (Time.Get() - LastSendTime > Time.Freq() / 2)
                {
                    SendControlMsg(ConnectionMessages.CONNECT, "");
                }
            }
        }
Beispiel #3
0
        public override bool QueueChunkEx(ChunkFlags flags, int dataSize, byte[] data, int sequence)
        {
            if (ResendQueueConstruct.DataSize +
                dataSize + NetworkCore.PACKET_HEADER_SIZE > NetworkCore.MAX_PAYLOAD)
            {
                Flush();
            }

            var header = new NetworkChunkHeader
            {
                Flags    = flags,
                Size     = dataSize,
                Sequence = sequence
            };

            var chunkDataOffset = ResendQueueConstruct.DataSize;

            chunkDataOffset = header.Pack(ResendQueueConstruct.Data, chunkDataOffset);

            Buffer.BlockCopy(data, 0, ResendQueueConstruct.Data, chunkDataOffset, dataSize);
            chunkDataOffset += dataSize;

            ResendQueueConstruct.NumChunks++;
            ResendQueueConstruct.DataSize = chunkDataOffset;

            if (flags.HasFlag(ChunkFlags.VITAL) && !flags.HasFlag(ChunkFlags.RESEND))
            {
                BufferSize += SIZEOF_NETWORK_CHUNK_RESEND + dataSize;
                if (BufferSize >= BUFFERSIZE)
                {
                    Disconnect("too weak connection (out of buffer)");
                    return(false);
                }

                var resend = new NetworkChunkResend
                {
                    Sequence      = sequence,
                    Flags         = flags,
                    DataSize      = dataSize,
                    Data          = new byte[dataSize],
                    FirstSendTime = Time.Get(),
                    LastSendTime  = Time.Get()
                };

                Buffer.BlockCopy(data, 0, resend.Data, 0, dataSize);
                ResendQueue.Enqueue(resend);
            }

            return(true);
        }
Beispiel #4
0
        public override void Reset()
        {
            Sequence     = 0;
            UnknownAck   = false;
            Ack          = 0;
            PeerAck      = 0;
            RemoteClosed = false;

            State           = ConnectionState.OFFLINE;
            ConnectedAt     = 0;
            LastReceiveTime = 0;
            LastSendTime    = 0;
            UseToken        = true;
            Token           = 0;

            EndPoint = null;

            ResendQueue.Clear();
            BufferSize = 0;

            Error = string.Empty;
            ResetQueueConstruct();
        }