private void DisconnectPeer( NetPeer peer, DisconnectReason reason, int socketErrorCode, bool sendDisconnectPacket, byte[] data, int start, int count) { if (sendDisconnectPacket) { if (count + 8 >= peer.Mtu) { //Drop additional data data = null; count = 0; NetUtils.DebugWriteError("[NM] Disconnect additional data size more than MTU - 8!"); } var disconnectPacket = _netPacketPool.Get(PacketProperty.Disconnect, 8 + count); FastBitConverter.GetBytes(disconnectPacket.RawData, 1, peer.ConnectId); if (data != null) { Buffer.BlockCopy(data, start, disconnectPacket.RawData, 9, count); } SendRawAndRecycle(disconnectPacket, peer.EndPoint); } var netEvent = CreateEvent(NetEventType.Disconnect); netEvent.Peer = peer; netEvent.AdditionalData = socketErrorCode; netEvent.DisconnectReason = reason; EnqueueEvent(netEvent); RemovePeer(peer.EndPoint); }
private void SendConnectRequest() { //Make initial packet var connectPacket = _packetPool.Get(PacketProperty.ConnectRequest, 12 + _connectData.Length); //Add data FastBitConverter.GetBytes(connectPacket.RawData, 1, NetConstants.ProtocolId); FastBitConverter.GetBytes(connectPacket.RawData, 5, _connectId); Buffer.BlockCopy(_connectData.Data, 0, connectPacket.RawData, 13, _connectData.Length); //Send raw _netManager.SendRawAndRecycle(connectPacket, _remoteEndPoint); }
internal NetPeer(NetManager peerListener, NetEndPoint remoteEndPoint, long connectId) { _packetPool = peerListener.PacketPool; _peerListener = peerListener; _remoteEndPoint = remoteEndPoint; _avgRtt = 0; _rtt = 0; _pingSendTimer = 0; _reliableOrderedChannel = new ReliableChannel(this, true, _windowSize); _reliableUnorderedChannel = new ReliableChannel(this, false, _windowSize); _sequencedChannel = new SequencedChannel(this); _simpleChannel = new SimpleChannel(this); _holdedFragments = new Dictionary <ushort, IncomingFragments>(); _mergeData = _packetPool.Get(PacketProperty.Merged, NetConstants.MaxPacketSize); //if ID != 0 then we already connected _connectAttempts = 0; if (connectId == 0) { _connectId = DateTime.UtcNow.Ticks; SendConnectRequest(); } else { _connectId = connectId; _connectionState = ConnectionState.Connected; SendConnectAccept(); } NetUtils.DebugWrite(ConsoleColor.Cyan, "[CC] ConnectId: {0}", _connectId); }
/// <summary> /// NetManager constructor /// </summary> /// <param name="listener">Network events listener</param> /// <param name="maxConnections">Maximum connections (incoming and outcoming)</param> public NetManager(INetEventListener listener, int maxConnections) { _logicThread = new Thread(UpdateLogic) { Name = "LogicThread", IsBackground = true }; _socket = new NetSocket(ReceiveLogic); _netEventListener = listener; _netEventsQueue = new SwitchQueue <NetEvent>(); _netEventsPool = new Stack <NetEvent>(); NetPacketPool = new NetPacketPool(); NatPunchModule = new NatPunchModule(this); Statistics = new NetStatistics(); _peers = new NetPeerCollection(maxConnections); _connectingPeers = new HashSet <NetEndPoint>(); _maxConnections = maxConnections; _updateTimeFilter = new long[3]; // Precreate all needed Merge Packets for (int i = 0; i < maxConnections * 3; ++i) { NetPacket p = NetPacketPool.Get(PacketProperty.Sequenced, 0, NetConstants.MaxPacketSize); p.Recycle(); } }
private void SendConnectRequest() { //Get connect key bytes byte[] keyData = Encoding.UTF8.GetBytes(_peerListener.ConnectKey); //Make initial packet var connectPacket = _packetPool.Get(PacketProperty.ConnectRequest, 12 + keyData.Length); //Add data FastBitConverter.GetBytes(connectPacket.RawData, 1, NetConstants.ProtocolId); FastBitConverter.GetBytes(connectPacket.RawData, 5, _connectId); Buffer.BlockCopy(keyData, 0, connectPacket.RawData, 13, keyData.Length); //Send raw _peerListener.SendRawAndRecycle(connectPacket, _remoteEndPoint); }
private NetPeer(NetManager netManager, NetEndPoint remoteEndPoint) { Statistics = new NetStatistics(); _packetPool = netManager.NetPacketPool; _netManager = netManager; _remoteEndPoint = remoteEndPoint; _avgRtt = 0; _rtt = 0; _pingSendTimer = 0; _reliableOrderedChannel = new ReliableChannel(this, true); _reliableUnorderedChannel = new ReliableChannel(this, false); _sequencedChannel = new SequencedChannel(this); _simpleChannel = new SimpleChannel(this); _reliableSequencedChannel = new ReliableSequencedChannel(this); _holdedFragments = new Dictionary <ushort, IncomingFragments>(); _mergeData = _packetPool.Get(PacketProperty.Merged, NetConstants.MaxPacketSize); }
//Update function private void UpdateLogic() { long startNowMs = NetTime.NowMs; NetPacket receiveBuffer = NetPacketPool.Get(PacketProperty.Sequenced, 0, NetConstants.MaxPacketSize); while (IsRunning) { #if DEBUG if (SimulateLatency) { var time = DateTime.UtcNow; lock (_pingSimulationList) { for (int i = 0; i < _pingSimulationList.Count; i++) { var incomingData = _pingSimulationList[i]; if (incomingData.TimeWhenGet <= time) { DataReceived(incomingData.Data, incomingData.Data.Length, incomingData.EndPoint); _pingSimulationList.RemoveAt(i); i--; } } } } #endif #if STATS_ENABLED ulong totalPacketLoss = 0; #endif // Flush disconnection first lock (_peers) { for (int i = 0; i < _peers.Count; i++) { NetPeer netPeer = _peers[i]; if (netPeer.ConnectionState == ConnectionState.Disconnected) { _peers.Remove(netPeer); } } //Process acks for (int i = 0; i < _peers.Count; i++) { NetPeer netPeer = _peers[i]; netPeer.Update(UpdateTime); #if STATS_ENABLED totalPacketLoss += netPeer.Statistics.PacketLoss; #endif } //Process ping for (int i = 0; i < _peers.Count; i++) { _peers[i].ProcessPong(UpdateTime); } } _socket.Receive(false, receiveBuffer.RawData); _socket.Receive(true, receiveBuffer.RawData); #if STATS_ENABLED Statistics.PacketLoss = totalPacketLoss; #endif Thread.Sleep(UpdateTime); long currentNowMs = NetTime.NowMs; long elapsedNowMs = currentNowMs - startNowMs; startNowMs = currentNowMs; AvgUpdateTime = (long)((elapsedNowMs * 6.0f + _updateTimeFilter[0] * 3.0f + _updateTimeFilter[1] * 2.0f + _updateTimeFilter[2] * 1.0f) / 12.0f); _updateTimeFilter[2] = _updateTimeFilter[1]; _updateTimeFilter[1] = _updateTimeFilter[0]; _updateTimeFilter[0] = elapsedNowMs; } }
private NetPeer(NetManager netManager, NetEndPoint remoteEndPoint) { Statistics = new NetStatistics(); _packetPool = netManager.NetPacketPool; _netManager = netManager; _remoteEndPoint = remoteEndPoint; if (netManager.MtuStartIdx >= 0 && netManager.MtuStartIdx < NetConstants.PossibleMtu.Length) { _mtuIdx = netManager.MtuStartIdx; _mtu = NetConstants.PossibleMtu[_mtuIdx]; _finishMtu = true; } _avgRtt = 0; _rtt = 0; _pingSendTimer = 0; _pingMustSend = false; if (NetManager.EnableReliableOrderedChannel) { _reliableOrderedChannels = new ReliableChannel[NetConstants.MultiChannelCount]; } if (NetManager.EnableReliableUnorderedChannel) { _reliableUnorderedChannels = new ReliableChannel[NetConstants.MultiChannelCount]; } if (NetManager.EnableSequencedChannel) { _sequencedChannels = new SequencedChannel[NetConstants.MultiChannelCount]; } if (NetManager.EnableSimpleChannel) { _simpleChannels = new SimpleChannel[NetConstants.MultiChannelCount]; } //_reliableSequencedChannels = new ReliableSequencedChannel[NetConstants.MultiChannelCount]; // Initialise default channel for (int i = 0; i < NetConstants.MultiChannelCount; ++i) { if (NetManager.EnableReliableOrderedChannel) { _reliableOrderedChannels[i] = new ReliableChannel(this, true, i); } if (NetManager.EnableReliableUnorderedChannel) { _reliableUnorderedChannels[i] = new ReliableChannel(this, false, i); } if (NetManager.EnableSequencedChannel) { _sequencedChannels[i] = new SequencedChannel(this, i); } if (NetManager.EnableSimpleChannel) { _simpleChannels[i] = new SimpleChannel(this, i); } //_reliableSequencedChannels[i] = new ReliableSequencedChannel(this, i); } _holdedFragments = new Dictionary <ushort, IncomingFragments>(); _mergeData = _packetPool.Get(PacketProperty.Merged, 0, NetConstants.MaxPacketSize); }