private void Connect(ITcpClient socket, AmqpTcpEndpoint endpoint, int timeout) { IAsyncResult ar = null; try { ar = socket.BeginConnect(endpoint.HostName, endpoint.Port, null, null); if (!ar.AsyncWaitHandle.WaitOne(timeout, false)) { socket.Close(); throw new TimeoutException("Connection to " + endpoint + " timed out"); } socket.EndConnect(ar); } catch (ArgumentException e) { throw new ConnectFailureException("Connection failed", e); } catch (SocketException e) { throw new ConnectFailureException("Connection failed", e); } finally { if (ar != null) { ar.AsyncWaitHandle.Close(); } } }
/// <summary> /// Connect to a Folding@Home client server. /// </summary> /// <param name="host">Hostname or IP address.</param> /// <param name="port">TCP port number.</param> /// <param name="password">Server password.</param> /// <exception cref="InvalidOperationException">Connection is already connected.</exception> /// <exception cref="ArgumentNullException"><paramref name="host"/> or <paramref name="password"/> is null.</exception> /// <exception cref="TimeoutException">Connection attempt timed out.</exception> public void Connect(string host, int port, string password) { // check connection status, callers should make sure no connection exists first if (Connected) throw new InvalidOperationException("Client is already connected."); if (host == null) throw new ArgumentNullException("host"); if (password == null) throw new ArgumentNullException("password"); if (_tcpClient != null) { _tcpClient.Dispose(); } _tcpClient = CreateClient(); IAsyncResult ar = _tcpClient.BeginConnect(host, port, null, null); try { if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(ConnectTimeout), false)) { _tcpClient.Close(); throw new TimeoutException("Client connection has timed out."); } _tcpClient.EndConnect(ar); _stream = _tcpClient.GetStream(); if (password.Length != 0) { // send authentication SendCommand("auth " + password); } if (Connected) { // send connected event OnConnectedChanged(new ConnectedChangedEventArgs(true)); // maybe use Connected property? // send status message OnStatusMessage(new StatusMessageEventArgs(String.Format(CultureInfo.CurrentCulture, "Connected to {0}:{1}", host, port), TraceLevel.Info)); // start listening for messages // from the network stream _timer.Start(); } } finally { ar.AsyncWaitHandle.Close(); } }
/// <summary> /// Connect to a Folding@Home client server. /// </summary> /// <param name="host">Hostname or IP address.</param> /// <param name="port">TCP port number.</param> /// <param name="password">Server password.</param> /// <exception cref="InvalidOperationException">Connection is already connected.</exception> /// <exception cref="ArgumentNullException"><paramref name="host"/> or <paramref name="password"/> is null.</exception> /// <exception cref="TimeoutException">Connection attempt timed out.</exception> public void Connect(string host, int port, string password) { // check connection status, callers should make sure no connection exists first if (Connected) { throw new InvalidOperationException("Client is already connected."); } if (host == null) { throw new ArgumentNullException("host"); } if (password == null) { throw new ArgumentNullException("password"); } if (_tcpClient != null) { _tcpClient.Dispose(); } _tcpClient = CreateClient(); IAsyncResult ar = _tcpClient.BeginConnect(host, port, null, null); try { if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(ConnectTimeout), false)) { _tcpClient.Close(); throw new TimeoutException("Client connection has timed out."); } _tcpClient.EndConnect(ar); _stream = _tcpClient.GetStream(); if (password.Length != 0) { // send authentication SendCommand("auth " + password); } if (Connected) { // send connected event OnConnectedChanged(new ConnectedChangedEventArgs(true)); // maybe use Connected property? // send status message OnStatusMessage(new StatusMessageEventArgs(String.Format(CultureInfo.CurrentCulture, "Connected to {0}:{1}", host, port), TraceLevel.Info)); // start listening for messages // from the network stream _timer.Start(); } } finally { /* * when running on Mono, if we time out connecting, * TcpClient.Close() (above) causes asynchronous access * (coming from BeginConnect-related path) to AsyncWaitHandle. * This opens a race window with closing the handle below. * * Unfortunate chain of events results in the following: * * Unhandled Exception: System.ObjectDisposedException: The object was used after being disposed. * at System.Threading.WaitHandle.CheckDisposed () * at System.Threading.EventWaitHandle.Set () * at (wrapper remoting-invoke-with-check) System.Threading.EventWaitHandle:Set () * at System.Net.Sockets.Socket+SocketAsyncResult.set_IsCompleted (Boolean value) * at System.Net.Sockets.Socket+SocketAsyncResult.Complete () * at System.Net.Sockets.Socket+SocketAsyncResult.Complete (System.Exception e) * at System.Net.Sockets.Socket+Worker.Connect () * at System.Net.Sockets.Socket+Worker.DispatcherCB (System.Net.Sockets.SocketAsyncResult sar) * * As Mono's TcpClient.Close() signals AsyncWaitHandle, we can * just wait on it before proceeding. * * Note: we can't wait on the handle right after closing TcpClient * because closing the client may throw. * */ if (IsRunningOnMono) { ar.AsyncWaitHandle.WaitOne(); } ar.AsyncWaitHandle.Close(); } }
/// <summary> /// Connect to a Folding@Home client server. /// </summary> /// <param name="host">Hostname or IP address.</param> /// <param name="port">TCP port number.</param> /// <param name="password">Server password.</param> /// <exception cref="InvalidOperationException">Connection is already connected.</exception> /// <exception cref="ArgumentNullException"><paramref name="host"/> or <paramref name="password"/> is null.</exception> /// <exception cref="TimeoutException">Connection attempt timed out.</exception> public void Connect(string host, int port, string password) { // check connection status, callers should make sure no connection exists first if (Connected) throw new InvalidOperationException("Client is already connected."); if (host == null) throw new ArgumentNullException("host"); if (password == null) throw new ArgumentNullException("password"); if (_tcpClient != null) { _tcpClient.Dispose(); } _tcpClient = CreateClient(); IAsyncResult ar = _tcpClient.BeginConnect(host, port, null, null); try { if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(ConnectTimeout), false)) { _tcpClient.Close(); throw new TimeoutException("Client connection has timed out."); } _tcpClient.EndConnect(ar); _stream = _tcpClient.GetStream(); if (password.Length != 0) { // send authentication SendCommand("auth " + password); } if (Connected) { // send connected event OnConnectedChanged(new ConnectedChangedEventArgs(true)); // maybe use Connected property? // send status message OnStatusMessage(new StatusMessageEventArgs(String.Format(CultureInfo.CurrentCulture, "Connected to {0}:{1}", host, port), TraceLevel.Info)); // start listening for messages // from the network stream _timer.Start(); } } finally { /* * when running on Mono, if we time out connecting, * TcpClient.Close() (above) causes asynchronous access * (coming from BeginConnect-related path) to AsyncWaitHandle. * This opens a race window with closing the handle below. * * Unfortunate chain of events results in the following: Unhandled Exception: System.ObjectDisposedException: The object was used after being disposed. at System.Threading.WaitHandle.CheckDisposed () at System.Threading.EventWaitHandle.Set () at (wrapper remoting-invoke-with-check) System.Threading.EventWaitHandle:Set () at System.Net.Sockets.Socket+SocketAsyncResult.set_IsCompleted (Boolean value) at System.Net.Sockets.Socket+SocketAsyncResult.Complete () at System.Net.Sockets.Socket+SocketAsyncResult.Complete (System.Exception e) at System.Net.Sockets.Socket+Worker.Connect () at System.Net.Sockets.Socket+Worker.DispatcherCB (System.Net.Sockets.SocketAsyncResult sar) * As Mono's TcpClient.Close() signals AsyncWaitHandle, we can * just wait on it before proceeding. * * Note: we can't wait on the handle right after closing TcpClient * because closing the client may throw. * */ if (IsRunningOnMono) { ar.AsyncWaitHandle.WaitOne(); } ar.AsyncWaitHandle.Close(); } }