Пример #1
0
        /// <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);
                }
            }
        }