调用reactor.run(),就会调用到mainloop函数,从而调用到select或epoll,监控fd的读写。
posixbase.py:
def listenTCP(self, port, factory, backlog=50, interface=''): p = tcp.Port(port, factory, backlog, interface, self) p.startListening()#会调用self.startReading(),再调用self.reactor.addReader(self)
#把自己加入epoll
return p def connectTCP(self, host, port, factory, timeout=30, bindAddress=None): c = tcp.Connector(host, port, factory, timeout, bindAddress, self) c.connect() return c
factory类负责connect的管理,比如connect的建立、丢失、失败等,procotol是负责数据的接收。
tcp.Connector(host, port, factory, timeout, bindAddress, self)
Connector类有factory,由factory可以找出procotol协议,协议主要是指tcp、process、ssl等。
class ClientCreator: """ Client connections that do not require a factory. The various connect* methods create a protocol instance using the given protocol class and arguments, and connect it, returning a Deferred of the resulting protocol instance. Useful for cases when we don't really need a factory. Mainly this is when there is no shared state between protocol instances, and no need to reconnect. The C{connectTCP}, C{connectUNIX}, and C{connectSSL} methods each return a L{Deferred} which will fire with an instance of the protocol class passed to L{ClientCreator.__init__}. These Deferred can be cancelled to abort the connection attempt (in a very unlikely case, cancelling the Deferred may not prevent the protocol from being instantiated and connected to a transport; if this happens, it will be disconnected immediately afterwards and the Deferred will still errback with L{CancelledError}). """ def __init__(self, reactor, protocolClass, *args, **kwargs): self.reactor = reactor self.protocolClass = protocolClass self.args = args self.kwargs = kwargs def _connect(self, method, *args, **kwargs): """ Initiate a connection attempt. @param method: A callable which will actually start the connection attempt. For example, C{reactor.connectTCP}. @param *args: Positional arguments to pass to C{method}, excluding the factory. @param **kwargs: Keyword arguments to pass to C{method}. @return: A L{Deferred} which fires with an instance of the protocol class passed to this L{ClientCreator}'s initializer or fails if the connection cannot be set up for some reason. """ def cancelConnect(deferred): connector.disconnect() if f.pending is not None: f.pending.cancel() d = defer.Deferred(cancelConnect)#会生成一个延迟对象 f = _InstanceFactory( self.reactor, self.protocolClass(*self.args, **self.kwargs), d) connector = method(factory=f, *args, **kwargs) return d def connectTCP(self, host, port, timeout=30, bindAddress=None): """ Connect to a TCP server. The parameters are all the same as to L{IReactorTCP.connectTCP} except that the factory parameter is omitted. @return: A L{Deferred} which fires with an instance of the protocol class passed to this L{ClientCreator}'s initializer or fails if the connection cannot be set up for some reason. """ return self._connect( self.reactor.connectTCP, host, port, timeout=timeout, bindAddress=bindAddress)#返回一个延迟对象
class BaseConnector: """Basic implementation of connector. State can be: "connecting", "connected", "disconnected" """ timeoutID = None factoryStarted = 0 def __init__(self, factory, timeout, reactor): self.state = "disconnected" self.reactor = reactor self.factory = factory self.timeout = timeout def disconnect(self): """Disconnect whatever our state is.""" if self.state == 'connecting': self.stopConnecting() elif self.state == 'connected': self.transport.loseConnection() def connect(self): """Start connection to remote server.""" if self.state != "disconnected": raise RuntimeError("can't connect in this state") self.state = "connecting" if not self.factoryStarted: self.factory.doStart() self.factoryStarted = 1 self.transport = transport = self._makeTransport()#创建一个client端 if self.timeout is not None: self.timeoutID = self.reactor.callLater(self.timeout, transport.failIfNotConnected, error.TimeoutError()) self.factory.startedConnecting(self)
重要结论:调用