private void OnIncomingConnection(IAsyncResult ar) { lock (SyncRoot) { if (IsDisposed) { return; } } NamedPipeServerStream socket = null; bool success = false; try { _pipe.EndWaitForConnection(ar); socket = _pipe; bool isAlreadyConnected; lock (SyncRoot) { isAlreadyConnected = InternalRemoteEndPoint != null || _isConnecting; _isConnecting = true; } if (isAlreadyConnected) { Log.InfoFormat("Blocking incoming connection from '', we're already connected to another endpoint"); } else { Log.DebugFormat("Incoming connection from '', starting handshake..."); var remoteEndPoint = NamedPipeEndPoint.FromClient(Name); var connectionId = PerformIncomingHandshake(_pipe, remoteEndPoint); FireOnConnected(remoteEndPoint, connectionId); success = true; } } catch (AuthenticationException e) { Log.WarnFormat("Closing connection: {0}", e); Disconnect(); } catch (Exception e) { Log.ErrorFormat("Caught exception while accepting incoming connection - disconnecting again: {0}", e); Disconnect(); } finally { if (!success) { if (socket != null) { try { socket.Disconnect(); } catch (Exception e) { Log.WarnFormat("Ignoring exception caught while disconnecting & disposing of socket: {0}", e); } } lock (SyncRoot) { if (!IsDisposed) { _pipe.BeginWaitForConnection(OnIncomingConnection, null); } } } _isConnecting = false; } }
/// <summary> /// /// </summary> /// <param name="endPoint"></param> /// <param name="timeout"></param> /// <param name="exception"></param> /// <param name="connectionId"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <exception cref="InvalidOperationException"></exception> public bool TryConnect(NamedPipeEndPoint endPoint, TimeSpan timeout, out Exception exception, out ConnectionId connectionId) { if (endPoint == null) { throw new ArgumentNullException(nameof(endPoint)); } if (Equals(endPoint, LocalEndPoint)) { throw new ArgumentException("An endPoint cannot be connected to itself", nameof(endPoint)); } if (endPoint.Type != NamedPipeEndPoint.PipeType.Server) { throw new ArgumentException("An endpoint can only establish a connection with a server-side enpoint", nameof(endPoint)); } if (timeout <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(timeout)); } if (IsConnected) { throw new InvalidOperationException( "This endPoint is already connected to another endPoint and cannot establish any more connections"); } bool success = false; NamedPipeClientStream pipe = null; try { var started = DateTime.Now; pipe = new NamedPipeClientStream(Localhost, endPoint.PipeName); try { var totalMilliseconds = (int)Math.Min(int.MaxValue, timeout.TotalMilliseconds); pipe.Connect(totalMilliseconds); } catch (TimeoutException e) { exception = new NoSuchNamedPipeEndPointException(endPoint, timeout, e); connectionId = ConnectionId.None; return(false); } catch (IOException e) { exception = new NoSuchNamedPipeEndPointException(endPoint, timeout, e); connectionId = ConnectionId.None; return(false); } catch (Exception e) { Log.ErrorFormat("Cauhgt unexpected exception while connecting to '{0}': {1}", endPoint, e); exception = new NoSuchNamedPipeEndPointException(endPoint, timeout, e); connectionId = ConnectionId.None; return(false); } var remaining = timeout - (DateTime.Now - started); ErrorType errorType; string error; object errorReason; if (!TryPerformOutgoingHandshake(pipe, remaining, out errorType, out error, out connectionId, out errorReason)) { switch (errorType) { case ErrorType.Handshake: exception = new HandshakeException(error); break; case ErrorType.AuthenticationRequired: exception = new AuthenticationRequiredException(error); break; case ErrorType.EndPointBlocked: exception = new RemoteEndpointAlreadyConnectedException(error, errorReason as EndPoint); break; default: exception = new AuthenticationException(error); break; } CurrentConnectionId = connectionId; return(false); } InternalRemoteEndPoint = endPoint; LocalEndPoint = NamedPipeEndPoint.FromClient(Name); Log.InfoFormat("EndPoint '{0}' successfully connected to '{1}'", Name, endPoint); FireOnConnected(endPoint, CurrentConnectionId); success = true; exception = null; return(true); } finally { if (!success) { if (pipe != null) { pipe.Close(); pipe.Dispose(); } InternalRemoteEndPoint = null; } } }