/// <summary> /// Connect the client (synchronous) /// </summary> /// <remarks> /// Please note that synchronous connect will not receive data automatically! /// You should use Receive() or ReceiveAsync() method manually after successful connection. /// </remarks> /// <returns>'true' if the client was successfully connected, 'false' if the client failed to connect</returns> public virtual bool Connect() { if (IsConnected || IsHandshaked || IsConnecting || IsHandshaking) { return(false); } // Setup buffers _receiveBuffer = new Buffer(); _sendBufferMain = new Buffer(); _sendBufferFlush = new Buffer(); // Setup event args _connectEventArg = new SocketAsyncEventArgs(); _connectEventArg.RemoteEndPoint = Endpoint; _connectEventArg.Completed += OnAsyncCompleted; // Create a new client socket Socket = CreateSocket(); // Apply the option: dual mode (this option must be applied before connecting) if (Socket.AddressFamily == AddressFamily.InterNetworkV6) { Socket.DualMode = OptionDualMode; } try { // Connect to the server Socket.Connect(Endpoint); } catch (SocketException ex) { // Close the client socket Socket.Close(); // Dispose the client socket Socket.Dispose(); // Dispose event arguments _connectEventArg.Dispose(); // Call the client disconnected handler SendError(ex.SocketErrorCode); OnDisconnected(); return(false); } // Update the client socket disposed flag IsSocketDisposed = false; // Apply the option: keep alive if (OptionKeepAlive) { Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); } // Apply the option: no delay if (OptionNoDelay) { Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); } // Prepare receive & send buffers _receiveBuffer.Reserve(OptionReceiveBufferSize); _sendBufferMain.Reserve(OptionSendBufferSize); _sendBufferFlush.Reserve(OptionSendBufferSize); // Reset statistic BytesPending = 0; BytesSending = 0; BytesSent = 0; BytesReceived = 0; // Update the connected flag IsConnected = true; // Call the client connected handler OnConnected(); try { // Create SSL stream _sslStreamId = Guid.NewGuid(); _sslStream = (Context.CertificateValidationCallback != null) ? new SslStream(new NetworkStream(Socket, false), false, Context.CertificateValidationCallback) : new SslStream(new NetworkStream(Socket, false), false); // SSL handshake _sslStream.AuthenticateAsClient(Address, Context.Certificates ?? new X509CertificateCollection(new[] { Context.Certificate }), Context.Protocols, true); } catch (Exception) { SendError(SocketError.NotConnected); DisconnectAsync(); return(false); } // Update the handshaked flag IsHandshaked = true; // Call the session handshaked handler OnHandshaked(); // Call the empty send buffer handler if (_sendBufferMain.IsEmpty) { OnEmpty(); } return(true); }