public AsyncConnectState(TorrentManager manager, Peer peer, IConnection connection, AsyncConnect callback) { Manager = manager; Peer = peer; Connection = connection; Callback = callback; }
/// <summary> /// Create connect probe /// </summary> /// <param name="index"></param> /// <param name="probe"></param> /// <param name="logger"></param> protected BaseConnectProbe(int index, IAsyncProbe probe, ILogger logger) { _probe = probe ?? throw new ArgumentNullException(nameof(probe)); _index = index; _logger = logger; _lock = new SemaphoreSlim(1, 1); _arg = new AsyncConnect(this); }
/// <summary> /// Initiates a connection to the server /// </summary> /// <param name="callback">AsyncCallback method</param> /// <param name="state">State object</param> /// <returns>IAsyncResult</returns> /// <example><code source="..\Examples\BeginConnect.cs" lang="cs" /></example> public IAsyncResult BeginConnect(AsyncCallback callback, object state) { AsyncConnect func; IAsyncResult ar; lock (m_asyncmethods) { ar = (func = new AsyncConnect(Connect)).BeginInvoke(callback, state); m_asyncmethods.Add(ar, func); } return(ar); }
/// <summary> /// Begin connecting to next endpoint /// </summary> private void OnBegin() { var exit = false; _lock.Wait(); try { while (!_cts.IsCancellationRequested && !exit) { IPEndPoint ep = null; var timeout = 3000; try { if (!Next(out ep, out timeout)) { exit = true; break; } } catch (OperationCanceledException) { exit = true; break; } catch (InvalidOperationException) { continue; } catch (Exception ex) { _logger.Error(ex, "Error getting endpoint for probe {index}", _index); exit = true; break; } if (_arg != null && _arg.IsRunning) { // Reset args since it is in running state and cannot be used... _logger.Verbose("Disposing args in running state."); DisposeArgsNoLock(); } while (!_cts.IsCancellationRequested) { if (_arg == null) { _arg = new AsyncConnect(this); } try { if (_arg.BeginConnect(ep, timeout)) { // Completed synchronously - go to next candidate break; } return; } catch (ObjectDisposedException) { // Try again } catch (InvalidOperationException) { // Operation in progress - try again } catch (SocketException sex) { if (sex.SocketErrorCode == SocketError.NoBufferSpaceAvailable || sex.SocketErrorCode == SocketError.TooManyOpenSockets) { if (ShouldGiveUp()) { // Exit only until we hit (approx.) min probe count. exit = true; break; } // Otherwise retry... } else { _logger.Error(sex, "{code} in connect of probe {index}...", sex.SocketErrorCode, _index); } } catch (Exception ex) { // Unexpected - shut probe down _logger.Error(ex, "Probe {index} has unexpected exception during connect.", _index); exit = true; break; } // Retry same endpoint address with new args DisposeArgsNoLock(); } if (exit) { // We failed, requeue the endpoint and kill this probe OnFail(ep); break; } } if (_cts.IsCancellationRequested) { return; } } finally { _lock.Release(); } if (exit) { // // We are here because we either... // // a) failed to dequeue // b) The producer has completed // c) Connect failed due to lack of ephimeral ports. // d) A non socket exception occurred. // // Notify of exit. // OnExit(); } }
/// <summary> /// /// </summary> /// <param name="settings"></param> public ConnectionManager(ClientEngine engine) { this.engine = engine; this.endCheckEncryptionCallback = delegate(IAsyncResult result) { ClientEngine.MainLoop.Queue(delegate { EndCheckEncryption(result); }); }; this.endSendMessageCallback = delegate(bool s, int c, object o) { ClientEngine.MainLoop.Queue(delegate { EndSendMessage(s, c, o); }); }; this.endCreateConnectionCallback = delegate(bool succeeded, object state) { ClientEngine.MainLoop.Queue(delegate { EndCreateConnection(succeeded, state); }); }; this.incomingConnectionAcceptedCallback = delegate(bool s, int c, object o) { ClientEngine.MainLoop.Queue(delegate { IncomingConnectionAccepted(s, c, o); }); }; this.bitfieldSentCallback = new MessagingCallback(PeerBitfieldSent); this.handshakeSentCallback = new MessagingCallback(this.PeerHandshakeSent); this.handshakeReceievedCallback = delegate(bool s, int c, object o) { ClientEngine.MainLoop.Queue(delegate { PeerHandshakeReceived(s, c, o); }); }; this.messageSentCallback = new MessagingCallback(this.PeerMessageSent); this.torrents = new MonoTorrentCollection<TorrentManager>(); }