'Attempts a connection to each resolved address, and returns a
connection which is established first.
@param protocolFactory: The protocol factory whose protocol
will be connected.
@type protocolFactory:
L{IProtocolFactory<twisted.internet.interfaces.IProtocolFactory>}
@return: A L{Deferred} that fires with the connected protocol
or fails a connection-related error.'

def connect(self, protocolFactory):

    if self._badHostname:
        return defer.fail(ValueError('invalid    hostname:    {}'.format(self._hostStr)))
    d = Deferred()
    addresses = []
    @provider(IResolutionReceiver)
    class EndpointReceiver(object, ):
        @staticmethod
        def resolutionBegan(resolutionInProgress):
            pass
        @staticmethod
        def addressResolved(address):
            addresses.append(address)
        @staticmethod
        def resolutionComplete():
            d.callback(addresses)
    self._nameResolver.resolveHostName(EndpointReceiver, self._hostText, portNumber=self._port)
    d.addErrback((lambda ignored: defer.fail(error.DNSLookupError("Couldn't    find    the    hostname    '{}'".format(self._hostStr)))))
    @d.addCallback
    def resolvedAddressesToEndpoints(addresses):
        for eachAddress in addresses:
            if isinstance(eachAddress, IPv6Address):
                (yield TCP6ClientEndpoint(self._reactor, eachAddress.host, eachAddress.port, self._timeout, self._bindAddress))
            if isinstance(eachAddress, IPv4Address):
                (yield TCP4ClientEndpoint(self._reactor, eachAddress.host, eachAddress.port, self._timeout, self._bindAddress))
    d.addCallback(list)
    def _canceller(d):
        d.errback(error.ConnectingCancelledError(HostnameAddress(self._hostBytes, self._port)))
    @d.addCallback
    def startConnectionAttempts(endpoints):
        '\n                                                Given    a    sequence    of    endpoints    obtained    via    name    resolution,    start\n                                                connecting    to    a    new    one    every    C{self._attemptDelay}    seconds    until\n                                                one    of    the    connections    succeeds,    all    of    them    fail,    or    the    attempt\n                                                is    cancelled.\n\n                                                @param    endpoints:    a    list    of    all    the    endpoints    we    might    try    to\n                                                                connect    to,    as    determined    by    name    resolution.\n                                                @type    endpoints:    L{list}    of    L{IStreamServerEndpoint}\n\n                                                @return:    a    Deferred    that    fires    with    the    result    of    the\n                                                                C{endpoint.connect}    method    that    completes    the    fastest,    or    fails\n                                                                with    the    first    connection    error    it    encountered    if    none    of    them\n                                                                succeed.\n                                                @rtype:    L{Deferred}    failing    with    L{error.ConnectingCancelledError}\n                                                                or    firing    with    L{IProtocol}\n                                                '
        if (not endpoints):
            raise error.DNSLookupError('no    results    for    hostname    lookup:    {}'.format(self._hostStr))
        iterEndpoints = iter(endpoints)
        pending = []
        failures = []
        winner = defer.Deferred(canceller=_canceller)
        def checkDone():
            if (pending or checkDone.completed or checkDone.endpointsLeft):
                return
            winner.errback(failures.pop())
        checkDone.completed = False
        checkDone.endpointsLeft = True
        @LoopingCall
        def iterateEndpoint():
            endpoint = next(iterEndpoints, None)
            if (endpoint is None):
                checkDone.endpointsLeft = False
                checkDone()
                return
            eachAttempt = endpoint.connect(protocolFactory)
            pending.append(eachAttempt)
            @eachAttempt.addBoth
            def noLongerPending(result):
                pending.remove(eachAttempt)
                return result
            @eachAttempt.addCallback
            def succeeded(result):
                winner.callback(result)
            @eachAttempt.addErrback
            def failed(reason):
                failures.append(reason)
                checkDone()
        iterateEndpoint.clock = self._reactor
        iterateEndpoint.start(self._attemptDelay)
        @winner.addBoth
        def cancelRemainingPending(result):
            checkDone.completed = True
            for remaining in pending[:]:
                remaining.cancel()
            if iterateEndpoint.running:
                iterateEndpoint.stop()
            return result
        return winner
    return d
