Exemplo n.º 1
0
        //Process incoming packet
        internal void ProcessPacket(NetPacket packet)
        {
            //not initialized
            if (_connectionState == ConnectionState.Outgoing)
            {
                _packetPool.Recycle(packet);
                return;
            }
            if (packet.ConnectionNumber != _connectNum && packet.Property != PacketProperty.ShutdownOk) //without connectionNum
            {
                NetDebug.Write(NetLogLevel.Trace, "[RR]Old packet");
                _packetPool.Recycle(packet);
                return;
            }
            _timeSinceLastPacket = 0;

            NetDebug.Write("[RR]PacketProperty: {0}", packet.Property);
            switch (packet.Property)
            {
            case PacketProperty.Merged:
                int pos = NetConstants.HeaderSize;
                while (pos < packet.Size)
                {
                    ushort size = BitConverter.ToUInt16(packet.RawData, pos);
                    pos += 2;
                    NetPacket mergedPacket = _packetPool.GetPacket(size, false);
                    if (!mergedPacket.FromBytes(packet.RawData, pos, size))
                    {
                        _packetPool.Recycle(packet);
                        break;
                    }
                    pos += size;
                    ProcessPacket(mergedPacket);
                }
                break;

            //If we get ping, send pong
            case PacketProperty.Ping:
                if (NetUtils.RelativeSequenceNumber(packet.Sequence, _pongPacket.Sequence) > 0)
                {
                    NetDebug.Write("[PP]Ping receive, send pong");
                    FastBitConverter.GetBytes(_pongPacket.RawData, 3, DateTime.UtcNow.Ticks);
                    _pongPacket.Sequence = packet.Sequence;
                    NetManager.SendRaw(_pongPacket, EndPoint);
                }
                _packetPool.Recycle(packet);
                break;

            //If we get pong, calculate ping time and rtt
            case PacketProperty.Pong:
                if (packet.Sequence == _pingPacket.Sequence)
                {
                    _pingTimer.Stop();
                    int elapsedMs = (int)_pingTimer.ElapsedMilliseconds;
                    _remoteDelta = BitConverter.ToInt64(packet.RawData, 3) + (elapsedMs * TimeSpan.TicksPerMillisecond) / 2 - DateTime.UtcNow.Ticks;
                    UpdateRoundTripTime(elapsedMs);
                    NetManager.ConnectionLatencyUpdated(this, elapsedMs / 2);
                    NetDebug.Write("[PP]Ping: {0} - {1} - {2}", packet.Sequence, elapsedMs, _remoteDelta);
                }
                _packetPool.Recycle(packet);
                break;

            case PacketProperty.Ack:
            case PacketProperty.Channeled:
                if (packet.ChannelId > _channels.Length)
                {
                    _packetPool.Recycle(packet);
                    break;
                }
                var channel = _channels[packet.ChannelId] ?? (packet.Property == PacketProperty.Ack ? null : CreateChannel(packet.ChannelId));
                if (channel != null)
                {
                    if (!channel.ProcessPacket(packet))
                    {
                        _packetPool.Recycle(packet);
                    }
                }
                break;

            //Simple packet without acks
            case PacketProperty.Unreliable:
                AddIncomingPacket(packet);
                return;

            case PacketProperty.MtuCheck:
            case PacketProperty.MtuOk:
                ProcessMtuPacket(packet);
                break;

            case PacketProperty.ShutdownOk:
                if (_connectionState == ConnectionState.ShutdownRequested)
                {
                    _connectionState = ConnectionState.Disconnected;
                }
                _packetPool.Recycle(packet);
                break;

            default:
                NetDebug.WriteError("Error! Unexpected packet type: " + packet.Property);
                break;
            }
        }
Exemplo n.º 2
0
        internal void Update(int deltaTime)
        {
            if (_connectionState == ConnectionState.Disconnected)
            {
                return;
            }

            _timeSinceLastPacket += deltaTime;
            if (_connectionState == ConnectionState.InProgress)
            {
                _connectTimer += deltaTime;
                if (_connectTimer > _peerListener.ReconnectDelay)
                {
                    _connectTimer = 0;
                    _connectAttempts++;
                    if (_connectAttempts > _peerListener.MaxConnectAttempts)
                    {
                        _connectionState = ConnectionState.Disconnected;
                        return;
                    }

                    //else send connect again
                    SendConnectRequest();
                }
                return;
            }

            //Get current flow mode
            int maxSendPacketsCount = _peerListener.GetPacketsPerSecond(_currentFlowMode);
            int currentMaxSend;

            if (maxSendPacketsCount > 0)
            {
                int availableSendPacketsCount = maxSendPacketsCount - _sendedPacketsCount;
                currentMaxSend = Math.Min(availableSendPacketsCount, (maxSendPacketsCount * deltaTime) / NetConstants.FlowUpdateTime);
            }
            else
            {
                currentMaxSend = int.MaxValue;
            }

            //DebugWrite("[UPDATE]Delta: {0}ms, MaxSend: {1}", deltaTime, currentMaxSend);

            //Pending acks
            _reliableOrderedChannel.SendAcks();
            _reliableUnorderedChannel.SendAcks();

            //ResetFlowTimer
            _flowTimer += deltaTime;
            if (_flowTimer >= NetConstants.FlowUpdateTime)
            {
                NetUtils.DebugWrite("[UPDATE]Reset flow timer, _sendedPackets - {0}", _sendedPacketsCount);
                _sendedPacketsCount = 0;
                _flowTimer          = 0;
            }

            //Send ping
            _pingSendTimer += deltaTime;
            if (_pingSendTimer >= _peerListener.PingInterval)
            {
                NetUtils.DebugWrite("[PP] Send ping...");

                //reset timer
                _pingSendTimer = 0;

                //send ping
                CreateAndSend(PacketProperty.Ping, _pingSequence);

                //reset timer
                _pingTimeStart = DateTime.UtcNow;
            }

            //RTT - round trip time
            _rttResetTimer += deltaTime;
            if (_rttResetTimer >= RttResetDelay)
            {
                _rttResetTimer = 0;
                //Rtt update
                _rtt  = _avgRtt;
                _ping = _avgRtt;
                _peerListener.ConnectionLatencyUpdated(this, _ping);
                _rttCount = 1;
            }

            //MTU - Maximum transmission unit
            if (!_finishMtu)
            {
                _mtuCheckTimer += deltaTime;
                if (_mtuCheckTimer >= MtuCheckDelay)
                {
                    _mtuCheckTimer = 0;
                    _mtuCheckAttempts++;
                    if (_mtuCheckAttempts >= MaxMtuCheckAttempts)
                    {
                        _finishMtu = true;
                    }
                    else
                    {
                        lock (_mtuMutex)
                        {
                            //Send increased packet
                            if (_mtuIdx < NetConstants.PossibleMtu.Length - 1)
                            {
                                int newMtu = NetConstants.PossibleMtu[_mtuIdx + 1] - NetConstants.HeaderSize;
                                var p      = _packetPool.Get(PacketProperty.MtuCheck, newMtu);
                                p.RawData[1] = (byte)(_mtuIdx + 1);
                                SendPacket(p);
                            }
                        }
                    }
                }
            }
            //MTU - end

            //Pending send
            lock (_flushLock)
            {
                SendQueuedPackets(currentMaxSend);
            }
        }
Exemplo n.º 3
0
        internal void Update(int deltaTime)
        {
            _timeSinceLastPacket += deltaTime;
            switch (_connectionState)
            {
            case ConnectionState.Connected:
                if (_timeSinceLastPacket > _netManager.DisconnectTimeout)
                {
                    NetUtils.DebugWrite(
                        "[UPDATE] Disconnect by timeout: {0} > {1}",
                        _timeSinceLastPacket,
                        _netManager.DisconnectTimeout);
                    _netManager.DisconnectPeerForce(this, DisconnectReason.Timeout, 0, null);
                    return;
                }
                break;

            case ConnectionState.ShutdownRequested:
                if (_timeSinceLastPacket > _netManager.DisconnectTimeout)
                {
                    _connectionState = ConnectionState.Disconnected;
                }
                else
                {
                    _shutdownTimer += deltaTime;
                    if (_shutdownTimer >= ShutdownDelay)
                    {
                        _shutdownTimer = 0;
                        _netManager.SendRaw(_shutdownPacket, _remoteEndPoint);
                    }
                }
                return;

            case ConnectionState.Outcoming:
                _connectTimer += deltaTime;
                if (_connectTimer > _netManager.ReconnectDelay)
                {
                    _connectTimer = 0;
                    _connectAttempts++;
                    if (_connectAttempts > _netManager.MaxConnectAttempts)
                    {
                        _netManager.DisconnectPeerForce(this, DisconnectReason.ConnectionFailed, 0, null);
                        return;
                    }

                    //else send connect again
                    _netManager.SendRaw(_connectRequestPacket, _remoteEndPoint);
                }
                return;

            case ConnectionState.Disconnected:
            case ConnectionState.Incoming:
                return;
            }

            //Send ping
            _pingSendTimer += deltaTime;
            if (_pingSendTimer >= _netManager.PingInterval)
            {
                NetUtils.DebugWrite("[PP] Send ping...");

                //reset timer
                _pingSendTimer = 0;

                //send ping
                _pingPacket.Sequence = _pingSequence;
                _netManager.SendRaw(_pingPacket, _remoteEndPoint);

                //reset timer
                _pingTimeStart = DateTime.UtcNow;
            }

            //RTT - round trip time
            _rttResetTimer += deltaTime;
            if (_rttResetTimer >= RttResetDelay)
            {
                _rttResetTimer = 0;
                //Rtt update
                _rtt  = _avgRtt;
                _ping = _avgRtt;
                _netManager.ConnectionLatencyUpdated(this, _ping);
                _rttCount = 1;
            }

            UpdateMtuLogic(deltaTime);

            //Pending send
            Flush();
        }
Exemplo n.º 4
0
        internal void Update(int deltaTime)
        {
            if (_connectionState == ConnectionState.Connected && _timeSinceLastPacket > _netManager.DisconnectTimeout)
            {
                NetUtils.DebugWrite(
                    "[UPDATE] Disconnect by timeout: {0} > {1}",
                    _timeSinceLastPacket,
                    _netManager.DisconnectTimeout);
                _netManager.DisconnectPeer(this, DisconnectReason.Timeout, 0, true, null, 0, 0);
                return;
            }
            if (_connectionState == ConnectionState.ShutdownRequested)
            {
                if (_timeSinceLastPacket > _netManager.DisconnectTimeout)
                {
                    _connectionState = ConnectionState.Disconnected;
                }
                else
                {
                    _netManager.SendRaw(_shutdownPacket.RawData, 0, _shutdownPacket.Size, _remoteEndPoint);
                }
                return;
            }
            if (_connectionState == ConnectionState.Disconnected)
            {
                return;
            }

            _timeSinceLastPacket += deltaTime;
            if (_connectionState == ConnectionState.InProgress)
            {
                _connectTimer += deltaTime;
                if (_connectTimer > _netManager.ReconnectDelay)
                {
                    _connectTimer = 0;
                    _connectAttempts++;
                    if (_connectAttempts > _netManager.MaxConnectAttempts)
                    {
                        _netManager.DisconnectPeer(this, DisconnectReason.ConnectionFailed, 0, true, null, 0, 0);
                        return;
                    }

                    //else send connect again
                    SendConnectRequest();
                }
                return;
            }

            //Send ping
            _pingSendTimer += deltaTime;
            if (_pingSendTimer >= _netManager.PingInterval)
            {
                NetUtils.DebugWrite("[PP] Send ping...");

                //reset timer
                _pingSendTimer = 0;

                //send ping
                CreateAndSend(PacketProperty.Ping, _pingSequence);

                //reset timer
                _pingTimeStart = DateTime.UtcNow;
            }

            //RTT - round trip time
            _rttResetTimer += deltaTime;
            if (_rttResetTimer >= RttResetDelay)
            {
                _rttResetTimer = 0;
                //Rtt update
                _rtt  = _avgRtt;
                _ping = _avgRtt;
                _netManager.ConnectionLatencyUpdated(this, _ping);
                _rttCount = 1;
            }

            //MTU - Maximum transmission unit
            if (!_finishMtu)
            {
                _mtuCheckTimer += deltaTime;
                if (_mtuCheckTimer >= MtuCheckDelay)
                {
                    _mtuCheckTimer = 0;
                    _mtuCheckAttempts++;
                    if (_mtuCheckAttempts >= MaxMtuCheckAttempts)
                    {
                        _finishMtu = true;
                    }
                    else
                    {
                        lock (_mtuMutex)
                        {
                            //Send increased packet
                            if (_mtuIdx < NetConstants.PossibleMtu.Length - 1)
                            {
                                int newMtu = NetConstants.PossibleMtu[_mtuIdx + 1] - NetConstants.HeaderSize;
                                var p      = _packetPool.Get(PacketProperty.MtuCheck, newMtu);
                                p.RawData[1] = (byte)(_mtuIdx + 1);
                                SendPacket(p);
                            }
                        }
                    }
                }
            }
            //MTU - end
            //Pending send
            Flush();
        }
Exemplo n.º 5
0
        internal void Update(int deltaTime)
        {
            if (_connectionState == ConnectionState.Disconnected)
            {
                return;
            }
            if (_connectionState == ConnectionState.InProgress)
            {
                _connectTimer += deltaTime;
                if (_connectTimer > _peerListener.ReconnectDelay)
                {
                    _connectTimer = 0;
                    _connectAttempts++;
                    if (_connectAttempts > _peerListener.MaxConnectAttempts)
                    {
                        _connectionState = ConnectionState.Disconnected;
                        return;
                    }

                    //else send connect again
                    SendConnectRequest();
                }
                return;
            }

            //Get current flow mode
            int maxSendPacketsCount = _peerListener.GetPacketsPerSecond(_currentFlowMode);
            int currentMaxSend;

            if (maxSendPacketsCount > 0)
            {
                int availableSendPacketsCount = maxSendPacketsCount - _sendedPacketsCount;
                currentMaxSend = Math.Min(availableSendPacketsCount, (maxSendPacketsCount * deltaTime) / NetConstants.FlowUpdateTime);
            }
            else
            {
                currentMaxSend = int.MaxValue;
            }

            DebugWrite("[UPDATE]Delta: {0}ms, MaxSend: {1}", deltaTime, currentMaxSend);

            //Pending acks
            _reliableOrderedChannel.SendAcks();
            _reliableUnorderedChannel.SendAcks();

            //Pending send
            int currentSended = 0;

            while (currentSended < currentMaxSend)
            {
                //Get one of packets
                if (_reliableOrderedChannel.SendNextPacket() ||
                    _reliableUnorderedChannel.SendNextPacket() ||
                    _sequencedChannel.SendNextPacket() ||
                    _simpleChannel.SendNextPacket())
                {
                    currentSended++;
                }
                else
                {
                    //no outgoing packets
                    break;
                }
            }

            //Increase counter
            _sendedPacketsCount += currentSended;

            //ResetFlowTimer
            _flowTimer += deltaTime;
            if (_flowTimer >= NetConstants.FlowUpdateTime)
            {
                DebugWrite("[UPDATE]Reset flow timer, _sendedPackets - {0}", _sendedPacketsCount);
                _sendedPacketsCount = 0;
                _flowTimer          = 0;
            }

            //Send ping
            _pingSendTimer += deltaTime;
            if (_pingSendTimer >= _peerListener.PingInterval)
            {
                DebugWrite("[PP] Send ping...");

                //reset timer
                _pingSendTimer = 0;

                //send ping
                CreateAndSend(PacketProperty.Ping, _pingSequence);

                //reset timer
                _pingTimeStart = DateTime.UtcNow;
            }

            //RTT - round trip time
            _rttResetTimer += deltaTime;
            if (_rttResetTimer >= RttResetDelay)
            {
                _rttResetTimer = 0;
                //Rtt update
                _rtt  = _avgRtt;
                _ping = _avgRtt;
                _peerListener.ConnectionLatencyUpdated(this, _ping);
                _rttCount = 1;
            }

            //MTU - Maximum transmission unit
            if (!_finishMtu)
            {
                _mtuCheckTimer += deltaTime;
                if (_mtuCheckTimer >= MtuCheckDelay)
                {
                    _mtuCheckTimer = 0;
                    _mtuCheckAttempts++;
                    if (_mtuCheckAttempts >= MaxMtuCheckAttempts)
                    {
                        _finishMtu = true;
                    }
                    else
                    {
                        lock (_mtuMutex)
                        {
                            //Send increased packet
                            if (_mtuIdx < NetConstants.PossibleMtu.Length - 1)
                            {
                                int newMtu = NetConstants.PossibleMtu[_mtuIdx + 1] - NetConstants.HeaderSize;
                                var p      = GetPacketFromPool(PacketProperty.MtuCheck, newMtu);
                                p.RawData[1] = (byte)(_mtuIdx + 1);
                                SendPacket(p);
                            }
                        }
                    }
                }
            }
            //MTU - end

            //Flush
            if (_mergePos > 0)
            {
                if (_mergeCount > 1)
                {
                    DebugWrite("Send merged: " + _mergePos + ", count: " + _mergeCount);
                    _peerListener.SendRaw(_mergeData.RawData, 0, NetConstants.HeaderSize + _mergePos, _remoteEndPoint);
                }
                else
                {
                    //Send without length information and merging
                    _peerListener.SendRaw(_mergeData.RawData, NetConstants.HeaderSize + 2, _mergePos - 2, _remoteEndPoint);
                }
                _mergePos   = 0;
                _mergeCount = 0;
            }
        }
Exemplo n.º 6
0
        internal void Update(int deltaTime)
        {
            if (_connectionState == ConnectionState.Connected && _timeSinceLastPacket > _netManager.DisconnectTimeout)
            {
                NetUtils.DebugWrite(
                    "[UPDATE] Disconnect by timeout: {0} > {1}",
                    _timeSinceLastPacket,
                    _netManager.DisconnectTimeout);
                _netManager.DisconnectPeer(this, DisconnectReason.Timeout, 0, true, null, 0, 0);
                return;
            }
            if (_connectionState == ConnectionState.ShutdownRequested)
            {
                if (_timeSinceLastPacket > _netManager.DisconnectTimeout)
                {
                    _connectionState = ConnectionState.Disconnected;
                }
                else
                {
                    _netManager.SendRaw(_shutdownPacket.RawData, 0, _shutdownPacket.Size, _remoteEndPoint);
                }
                return;
            }
            if (_connectionState == ConnectionState.Disconnected)
            {
                return;
            }

            _timeSinceLastPacket += deltaTime;
            if (_connectionState == ConnectionState.InProgress)
            {
                _connectTimer += deltaTime;
                if (_connectTimer > _netManager.ReconnectDelay)
                {
                    _connectTimer = 0;
                    _connectAttempts++;
                    if (_connectAttempts > _netManager.MaxConnectAttempts)
                    {
                        _netManager.DisconnectPeer(this, DisconnectReason.ConnectionFailed, 0, true, null, 0, 0);
                        return;
                    }

                    //else send connect again
                    SendConnectRequest();
                }
                return;
            }

            //Send ping
            _pingSendTimer += deltaTime;
            if (_pingSendTimer >= _netManager.PingInterval)
            {
                NetUtils.DebugWrite("[PP] Send ping...");

                //reset timer
                _pingSendTimer = 0;

                //send ping
                CreateAndSend(PacketProperty.Ping, _pingSequence);

                //reset timer
                _pingTimeStart = DateTime.UtcNow;
            }

            //RTT - round trip time
            _rttResetTimer += deltaTime;
            if (_rttResetTimer >= RttResetDelay)
            {
                _rttResetTimer = 0;
                //Rtt update
                _rtt  = _avgRtt;
                _ping = _avgRtt;
                _netManager.ConnectionLatencyUpdated(this, _ping);
                _rttCount = 1;
            }

            //Pending send
            Flush();
        }