private Task <bool> StartListenAsync() { if (_serverOption.IsServiceUdp == true) { _udpSocket = new UdpSocketEx(_loggerFactory.CreateLogger("ServerUdpSocket"), OnPreProcessUdpRawData); var udpEndPoint = NetUtil.GetEndPoint(_serverOption.UdpServerAddress, _serverOption.UdpServerPort); if (_udpSocket.CreateServer(udpEndPoint, _serverOption.UdpReuseAddress) == false) { _logger.LogError($"Failed to bind udp server : {_udpSocket.LocalPort}"); return(Task.FromResult(false)); } } _listener = new TcpListener(_serverOption, _loggerFactory.CreateLogger("TcpListener")); _listener.NewClientAccepted += OnNewClientAccept; if (!_listener.Start()) { _logger.LogError($"Failed to listen {_listener}."); return(Task.FromResult(false)); } return(Task.FromResult(true)); }
public void Close() { _cts.Cancel(); NetPacket poolingPacket; while (_receivedPacketQueue.TryDequeue(out poolingPacket) == true && poolingPacket != null) { NetPool.PacketPool.Free(poolingPacket); } try { _udpChannel?.Close(); _udpChannel?.OnClosed(); _udpSocket?.Close(false); _udpSocket = null; _request.Close(); } catch { } }
/// <summary> /// 서버와 접속을 해제하고 리소스를 해제한다 /// </summary> public void Close() { OnSessionClosed(); try { _cts.Cancel(); } catch { } NetPacket poolingPacket = null; while (_receivedPacketQueue.TryDequeue(out poolingPacket) == true && poolingPacket != null) { NetPool.PacketPool.Free(poolingPacket); } try { _tcpChannel?.Close(); _udpChannel?.Close(); _p2pGroup?.Close(); _p2pGroup = null; if (_connectUdpLoopTask != null) { _connectUdpLoopTask = null; } _udpSocket?.Close(false); _udpSocket = null; _request.Close(); } catch { } _socket = null; _isUdpConnected = false; }
public P2pSession(NetClient netClient, ushort sessionId, IPEndPoint remoteEp, IPEndPoint localEp) { _netClient = netClient; _sessionId = sessionId; _cts = new CancellationTokenSource(); _udpSocket = new UdpSocketEx( netClient.LoggerFactory.CreateLogger("P2pSessionUdpSocket"), netClient.OnPreProcessUdpRawData, netClient.UdpSocketReceiveRawAsyncObject); _udpSocket.CreateClient(); _tcpChannel = null; _udpChannel = new UdpChannel( _netClient.ClientOption, _netClient.LoggerFactory.CreateLogger(nameof(UdpChannel)), _netClient.Statistic, sessionId); _udpChannel.Init(_cts); _udpChannel.PacketReceived = OnReceiveFromChannel; _udpChannel.SetSocket(netClient.UdpSocket); _udpChannel.RemoteEndPoint = remoteEp; _udpChannel.LocalEndPoint = localEp; _udpChannel.TempEndPoint = remoteEp; _udpChannel.RelayEndPoint = NetUtil.GetEndPoint(netClient.ClientOption.UdpServerAddress, netClient.ClientOption.UdpServerPort); _udpChannel.IsRunMtu = false; _udpChannel.IsRunPing = false; _receivedPacketQueue = new ConcurrentQueue <NetPacket>(); _packetReader = new NetDataReader(); _request = new SessionRequest(this, netClient.Statistic); _state = SessionState.Connected; }
/// <summary> /// 서버를 정지 /// </summary> public async Task StopAsync() { var state = _state; if (state != ServerState.Started) { throw new InvalidOperationException($"The server cannot be stopped right now, because its state is {state}."); } _state = ServerState.Stopping; _logger.LogInformation("Stopping... listener"); if (_listener.IsRunning) { await _listener.StopAsync(); } _logger.LogInformation("Stopping... all session"); await _sessionFactory.ShutdownAsync(); _updateThread.Join(); _updateThread = null; if (_udpSocket != null) { _logger.LogInformation("Stopping... udp service"); _udpSocket.Close(false); _udpSocket = null; } _p2pManager?.Clear(); _logger.LogInformation("Stopped!"); _state = ServerState.Stopped; }
/// <summary> /// 서버로 연결을 시도합니다 /// </summary> /// <param name="timeout">타임아웃</param> /// <returns>성공여부</returns> public async Task <bool> ConnectAsync(TimeSpan?timeout = null) { if (_socket != null || State != SessionState.Closed) { return(false); } try { State = SessionState.Initialized; TimeSpan currentTimeout = timeout ?? TimeSpan.FromSeconds(10); _cts = new CancellationTokenSource(); _serverEndPoint = NetUtil.GetEndPoint(_clientOption.TcpServerAddress, _clientOption.TcpServerPort); _serverUdpEndPoint = NetUtil.GetEndPoint(_clientOption.UdpServerAddress, _clientOption.UdpServerPort); if (_clientOption.IsServiceUdp) { _udpSocket = new UdpSocketEx( _loggerFactory.CreateLogger("ClientUdpSocket"), OnPreProcessUdpRawData, UdpSocketReceiveRawAsyncObject); _udpSocket.CreateClient(); } _isUdpConnected = false; _socket = new Socket(SocketType.Stream, ProtocolType.Tcp); await _socket.ConnectAsync(_serverEndPoint).TimeoutAfter(currentTimeout); if (_socket.Connected == false) { _logger.LogInformation("Fail to connect"); State = SessionState.Closed; _socket.Close(); _socket = null; return(false); } if (_tcpChannel != null) { _tcpChannel.Init(_cts); _tcpChannel.PacketReceived = OnReceiveFromChannel; _tcpChannel.SetSocket(_socket); } if (_udpChannel != null) { _udpChannel.Init(_cts); _udpChannel.PacketReceived = OnReceiveFromChannel; if (_udpSocket != null) { _udpChannel.SetSocket(_udpSocket); _udpChannel.LocalEndPoint = _udpSocket.GetLocalEndPoint(); } } RunAsync().DoNotAwait(); if (_clientOption.IsServiceUdp) { currentTimeout = TimeSpan.FromSeconds(10); while (IsUdpConnected == false && State == SessionState.Initialized) { await Task.Delay(100); currentTimeout -= TimeSpan.FromMilliseconds(100); if (currentTimeout < TimeSpan.FromMilliseconds(0)) { throw new Exception("udp connection timeout"); } } } OnSessionConnected(); _logger.LogInformation("Connect succeed"); return(true); } catch (Exception ex) { OnError(ex); Close(); } State = SessionState.Closed; return(false); }