internal void FlushMergePacket() { //If merging enabled if (_mergePos > 0) { if (_mergeCount > 1) { NetUtils.DebugWrite("Send merged: " + _mergePos + ", count: " + _mergeCount); _mergeData.Size = NetConstants.HeaderSize + _mergePos; _mergeData.Property = PacketProperty.Merged; _mergeData.Prepare(); _netManager.SendRaw(_mergeData.RawData, 0, _mergeData.Size, _remoteEndPoint); #if STATS_ENABLED Statistics.PacketsSent++; Statistics.BytesSent += (ulong)(NetConstants.HeaderSize + _mergePos); #endif } else { //Send without length information and merging _netManager.SendRaw(_mergeData.RawData, sizeof(ushort), _mergePos - sizeof(ushort), _remoteEndPoint); #if STATS_ENABLED Statistics.PacketsSent++; Statistics.BytesSent += (ulong)(_mergePos - 2); #endif } _mergePos = 0; _mergeCount = 0; } }
internal void SendRawData(NetPacket packet) { packet.Prepare(); //2 - merge byte + minimal packet size + datalen(ushort) if (_netManager.MergeEnabled && CanMerge(packet.Property)) { if (_mergePos + packet.Size + sizeof(ushort) >= _mtu) { FlushMergePacket(); } FastBitConverter.GetBytes(_mergeData.RawData, _mergePos, (ushort)packet.Size); Buffer.BlockCopy(packet.RawData, 0, _mergeData.RawData, _mergePos + sizeof(ushort), packet.Size); _mergePos += packet.Size + sizeof(ushort); _mergeCount++; //DebugWriteForce("Merged: " + _mergePos + "/" + (_mtu - 2) + ", count: " + _mergeCount); return; } NetUtils.DebugWrite(ConsoleColor.DarkYellow, "[P]SendingPacket: " + packet.Property); _netManager.SendRaw(packet.RawData, 0, packet.Size, _remoteEndPoint); #if STATS_ENABLED Statistics.PacketsSent++; Statistics.BytesSent += (ulong)packet.Size; #endif }
internal bool SendRawAndRecycle(NetPacket packet, NetEndPoint remoteEndPoint) { packet.Prepare(); var result = SendRaw(packet.RawData, 0, packet.Size, remoteEndPoint); NetPacketPool.Recycle(packet); return(result); }
internal void Update(int deltaTime) { if ((_connectionState == ConnectionState.Connected || _connectionState == ConnectionState.ShutdownRequested) && _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) { _shutdownPacket.Prepare(); _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 = NetTime.NowMs; } //RTT - round trip time _rttResetTimer += deltaTime; if (_rttResetTimer >= RttResetDelay) { _rttResetTimer = 0; //Rtt update _rtt = _avgRtt; _ping = (int)_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, 0, newMtu); p.RawData[0] = (byte)(_mtuIdx + 1); SendPacket(p); } } } } } //MTU - end //Pending send Flush(); }