def doConnect(self): """I connect the socket. Then, call the protocol's makeConnection, and start waiting for data. """ if not hasattr(self, "connector"): # this happens when connection failed but doConnect # was scheduled via a callLater in self._finishInit return # on windows failed connects are reported on exception # list, not write or read list. if platformType == "win32" or sys.platform == "cygwin": r, w, e = select.select([], [], [self.fileno()], 0.0) if e: err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) self.failIfNotConnected( error.getConnectError((err, os.strerror(err)))) return try: connectResult = self.socket.connect_ex(self.realAddress) except socket.error, se: connectResult = se.args[0]
def doConnect(self): """I connect the socket. Then, call the protocol's makeConnection, and start waiting for data. """ if not hasattr(self, "connector"): # this happens when connection failed but doConnect # was scheduled via a callLater in self._finishInit return err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) if err: self.failIfNotConnected( error.getConnectError((err, os.strerror(err)))) return # doConnect gets called twice. The first time we actually need to # start the connection attempt. The second time we don't really # want to (SO_ERROR above will have taken care of any errors, and if # it reported none, the mere fact that doConnect was called again is # sufficient to indicate that the connection has succeeded), but it # is not /particularly/ detrimental to do so. This should get # cleaned up some day, though. try: connectResult = self.socket.connect_ex(self.realAddress) except socket.error, se: connectResult = se.args[0]
def doConnect(self): """I connect the socket. Then, call the protocol's makeConnection, and start waiting for data. """ if not hasattr(self, "connector"): # this happens when connection failed but doConnect # was scheduled via a callLater in self._finishInit return err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) if err: self.failIfNotConnected(error.getConnectError((err, os.strerror(err)))) return # doConnect gets called twice. The first time we actually need to # start the connection attempt. The second time we don't really # want to (SO_ERROR above will have taken care of any errors, and if # it reported none, the mere fact that doConnect was called again is # sufficient to indicate that the connection has succeeded), but it # is not /particularly/ detrimental to do so. This should get # cleaned up some day, though. try: connectResult = self.socket.connect_ex(self.realAddress) except socket.error, se: connectResult = se.args[0]
def doConnect(self): """I connect the socket. Then, call the protocol's makeConnection, and start waiting for data. """ if not hasattr(self, "connector"): return if platformType == "win32" or sys.platform == "cygwin": r, w, e = select.select([], [], [self.fileno()], 0.0) if e: err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) self.failIfNotConnected(error.getConnectError((err, os.strerror(err)))) return try: connectResult = self.socket.connect_ex(self.realAddress) except socket.error, se: connectResult = se.args[0]
def doConnect(self): """I connect the socket. Then, call the protocol's makeConnection, and start waiting for data. """ if not hasattr(self, "connector"): # this happens when connection failed but doConnect # was scheduled via a callLater in self._finishInit return # on windows failed connects are reported on exception # list, not write or read list. if platformType == "win32" or sys.platform == "cygwin": r, w, e = select.select([], [], [self.fileno()], 0.0) if e: err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) self.failIfNotConnected(error.getConnectError((err, strerror(err)))) return try: connectResult = self.socket.connect_ex(self.realAddress) except socket.error, se: connectResult = se.args[0]
def threadedThing(self, sock, addr): res = sock.connect_ex(addr) if res: raise error.getConnectError((res, os.strerror(res)))
class BaseClient(Connection): """A base class for client TCP (and similiar) sockets. """ addressFamily = socket.AF_INET socketType = socket.SOCK_STREAM def _finishInit(self, whenDone, skt, error, reactor): """Called by base classes to continue to next stage of initialization.""" if whenDone: Connection.__init__(self, skt, None, reactor) self.doWrite = self.doConnect self.doRead = self.doConnect reactor.callLater(0, whenDone) else: reactor.callLater(0, self.failIfNotConnected, error) def startTLS(self, ctx, client=1): holder = Connection.startTLS(self, ctx) if client: self.socket.set_connect_state() else: self.socket.set_accept_state() return holder def stopConnecting(self): """Stop attempt to connect.""" self.failIfNotConnected(error.UserError()) def failIfNotConnected(self, err): if (self.connected or self.disconnected or not hasattr(self, "connector")): return try: self._closeSocket() except AttributeError: pass else: del self.socket, self.fileno self.connector.connectionFailed(failure.Failure(err)) if hasattr(self, "reactor"): # this doesn't happen if we failed in __init__ self.stopReading() self.stopWriting() del self.connector def createInternetSocket(self): """(internal) Create a non-blocking socket using self.addressFamily, self.socketType. """ s = socket.socket(self.addressFamily, self.socketType) s.setblocking(0) if fcntl and hasattr(fcntl, 'FD_CLOEXEC'): old = fcntl.fcntl(s.fileno(), fcntl.F_GETFD) fcntl.fcntl(s.fileno(), fcntl.F_SETFD, old | fcntl.FD_CLOEXEC) return s def resolveAddress(self): if abstract.isIPAddress(self.addr[0]): self._setRealAddress(self.addr[0]) else: d = self.reactor.resolve(self.addr[0]) d.addCallbacks(self._setRealAddress, self.failIfNotConnected) def _setRealAddress(self, address): self.realAddress = (address, self.addr[1]) self.doConnect() def doConnect(self): """I connect the socket. Then, call the protocol's makeConnection, and start waiting for data. """ if not hasattr(self, "connector"): # this happens when connection failed but doConnect # was scheduled via a callLater in self._finishInit return # on windows failed connects are reported on exception # list, not write or read list. if platformType == "win32" or sys.platform == "cygwin": r, w, e = select.select([], [], [self.fileno()], 0.0) if e: err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) self.failIfNotConnected( error.getConnectError((err, os.strerror(err)))) return try: connectResult = self.socket.connect_ex(self.realAddress) except socket.error, se: connectResult = se.args[0] if connectResult: if connectResult == EISCONN: pass # on Windows EINVAL means sometimes that we should keep trying: # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/connect_2.asp elif ((connectResult in (EWOULDBLOCK, EINPROGRESS, EALREADY)) or (connectResult == EINVAL and platformType == "win32")): self.startReading() self.startWriting() return else: self.failIfNotConnected( error.getConnectError( (connectResult, os.strerror(connectResult)))) return # If I have reached this point without raising or returning, that means # that the socket is connected. del self.doWrite del self.doRead # we first stop and then start, to reset any references to the old doRead self.stopReading() self.stopWriting() self._connectDone()
class BaseClient(Connection): """A base class for client TCP (and similiar) sockets. """ addressFamily = socket.AF_INET socketType = socket.SOCK_STREAM def _finishInit(self, whenDone, skt, error, reactor): """Called by base classes to continue to next stage of initialization.""" if whenDone: Connection.__init__(self, skt, None, reactor) self.doWrite = self.doConnect self.doRead = self.doConnect reactor.callLater(0, whenDone) else: reactor.callLater(0, self.failIfNotConnected, error) def startTLS(self, ctx, client=1): holder = Connection.startTLS(self, ctx) if client: self.socket.set_connect_state() else: self.socket.set_accept_state() return holder def stopConnecting(self): """Stop attempt to connect.""" self.failIfNotConnected(error.UserError()) def failIfNotConnected(self, err): """ Generic method called when the attemps to connect failed. It basically cleans everything it can: call connectionFailed, stop read and write, delete socket related members. """ if (self.connected or self.disconnected or not hasattr(self, "connector")): return self.connector.connectionFailed(failure.Failure(err)) if hasattr(self, "reactor"): # this doesn't happen if we failed in __init__ self.stopReading() self.stopWriting() del self.connector try: self._closeSocket() except AttributeError: pass else: del self.socket, self.fileno def createInternetSocket(self): """(internal) Create a non-blocking socket using self.addressFamily, self.socketType. """ s = socket.socket(self.addressFamily, self.socketType) s.setblocking(0) if fcntl and hasattr(fcntl, 'FD_CLOEXEC'): old = fcntl.fcntl(s.fileno(), fcntl.F_GETFD) fcntl.fcntl(s.fileno(), fcntl.F_SETFD, old | fcntl.FD_CLOEXEC) return s def resolveAddress(self): if abstract.isIPAddress(self.addr[0]): self._setRealAddress(self.addr[0]) else: d = self.reactor.resolve(self.addr[0]) d.addCallbacks(self._setRealAddress, self.failIfNotConnected) def _setRealAddress(self, address): self.realAddress = (address, self.addr[1]) self.doConnect() def doConnect(self): """I connect the socket. Then, call the protocol's makeConnection, and start waiting for data. """ if not hasattr(self, "connector"): # this happens when connection failed but doConnect # was scheduled via a callLater in self._finishInit return err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) if err: self.failIfNotConnected( error.getConnectError((err, os.strerror(err)))) return # doConnect gets called twice. The first time we actually need to # start the connection attempt. The second time we don't really # want to (SO_ERROR above will have taken care of any errors, and if # it reported none, the mere fact that doConnect was called again is # sufficient to indicate that the connection has succeeded), but it # is not /particularly/ detrimental to do so. This should get # cleaned up some day, though. try: connectResult = self.socket.connect_ex(self.realAddress) except socket.error, se: connectResult = se.args[0] if connectResult: if connectResult == EISCONN: pass # on Windows EINVAL means sometimes that we should keep trying: # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/connect_2.asp elif ((connectResult in (EWOULDBLOCK, EINPROGRESS, EALREADY)) or (connectResult == EINVAL and platformType == "win32")): self.startReading() self.startWriting() return else: self.failIfNotConnected( error.getConnectError( (connectResult, os.strerror(connectResult)))) return # If I have reached this point without raising or returning, that means # that the socket is connected. del self.doWrite del self.doRead # we first stop and then start, to reset any references to the old doRead self.stopReading() self.stopWriting() self._connectDone()