/// <summary> /// Establishes a connection to a remote host. /// </summary> /// <param name="remoteHostOrIp">A value containing the Hostname or IP address of the remote host.</param> /// <param name="remotePort">A value indicating the port on the remote host to connect to.</param> /// <param name="sslHost">The name of the host to validate the certificate for.</param> /// <param name="localIp">A value indicating the IP address the client should connect from.</param> /// <param name="localPort">A value indicating the port the client should connect from.</param> public async void Connect(string remoteHostOrIp, int remotePort, string sslHost, string localIp, int localPort) { if (Parent.State != State.Closed) { throw new WinsockException("Cannot connect to a remote host when not Closed."); } /** * First we need to make sure we have an IP address. * If not - we need to try and resolve the fully qualified domain. */ Parent.ChangeState(State.ResolvingHost); IPAddress resolvedRemoteIP = null, resolvedLocalIP = null; if (!IPAddress.TryParse(remoteHostOrIp, out resolvedRemoteIP)) { IPHostEntry entry = await Dns.GetHostEntryAsync(remoteHostOrIp); if (entry == null || entry.AddressList.Length == 0) { string name = (entry != null) ? entry.HostName : remoteHostOrIp; throw new WinsockException(string.Format("Hostname \"{0}\" could not be resolved.", name)); } resolvedRemoteIP = entry.AddressList[0]; } if (!string.IsNullOrWhiteSpace(localIp) && !IPAddress.TryParse(localIp, out resolvedLocalIP)) { throw new WinsockException(string.Format("The value \"{0}\" is not a valid IP address for local binding.", localIp)); } Parent.ChangeState(State.HostResolved); /** * Take our IP address and attempt to create the connection. * Upon successfull connections - different BeginReceives could be called * depending on if this was an attempt at a SECURE connection. */ IPEndPoint endPoint = new IPEndPoint(resolvedRemoteIP, remotePort); IPEndPoint localEndPoint = (resolvedLocalIP != null) ? new IPEndPoint(resolvedLocalIP, localPort) : null; socket = new AsyncSocket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); Parent.ChangeState(State.Connecting); bool connectFail = false; try { if (localEndPoint != null) { socket.Bind(localEndPoint); } await socket.ConnectAsync(endPoint); } catch (Exception ex) { connectFail = true; Parent.ChangeState(State.Closed); Parent.OnErrorReceived(Parent, ErrorReceivedEventArgs.Create(ex)); } if (!connectFail) { Parent.ChangeState(State.Connected); Parent.OnConnected(endPoint); if (sslHost != null) { BeginReceive(false, sslHost); } else { BeginReceive(false); } } }