twisted的几个核心组件protocol,transport,factory,defer,reactor,把这几个关键组件搞清楚了,也就算是twisted入门了,大致关系是这样的由reactor来形成消息循环(和windows的消息循环机制类似),等到socket完成后通过defer(延迟通知技术,也就是基于这个事件的驱动),去调用相应的响应函数来实现异步操作。twisted的调用框架会首先找到监听(或连接,如果是客户端的话)的工厂,根据工厂的接口buildProtocol来构建相应的协议,其实最有必要的是去了解和研究twisted.internet的interfaces模块,这里模块讲解了所有组件的接口(这些接口均是从zope.inteferace衍生过来的),下面看下twisted.internet.interfaces的IProtocolFactory,ITransport,IProtocol接口类
class IProtocolFactory(Interface): """ Interface for protocol factories. """ def buildProtocol(addr): """ Called when a connection has been established to addr. If None is returned, the connection is assumed to have been refused, and the Port will close the connection. @type addr: (host, port) @param addr: The address of the newly-established connection @return: None if the connection was refused, otherwise an object providing L{IProtocol}. """ def doStart(): """ Called every time this is connected to a Port or Connector. """ def doStop(): """ Called every time this is unconnected from a Port or Connector. """ class ITransport(Interface): """ I am a transport for bytes. I represent (and wrap) the physical connection and synchronicity of the framework which is talking to the network. I make no representations about whether calls to me will happen immediately or require returning to a control loop, or whether they will happen in the same or another thread. Consider methods of this class (aside from getPeer) to be 'thrown over the wall', to happen at some indeterminate time. class IProtocol(Interface): def dataReceived(data): """ Called whenever data is received. Use this method to translate to a higher-level message. Usually, some callback will be made upon the receipt of each complete protocol message. @param data: a string of indeterminate length. Please keep in mind that you will probably need to buffer some data, as partial (or multiple) protocol messages may be received! I recommend that unit tests for protocols call through to this method with differing chunk sizes, down to one byte at a time. """ def connectionLost(reason): """ Called when the connection is shut down. Clear any circular references here, and any external references to this Protocol. The connection has been closed. The C{reason} Failure wraps a L{twisted.internet.error.ConnectionDone} or L{twisted.internet.error.ConnectionLost} instance (or a subclass of one of those). @type reason: L{twisted.python.failure.Failure} """ def makeConnection(transport): """ Make a connection to a transport and a server. """ def connectionMade(): """ Called when a connection is made. This may be considered the initializer of the protocol, because it is called when the connection is completed. For clients, this is called once the connection to the server has been established; for servers, this is called after an accept() call stops blocking and a socket has been received. If you need to send any greeting or initial message, do it here. """
这里提供了所有组件的核心接口。
下面看看我写的例子代码
echo_client.py
from twisted.internet.protocol import Protocol, ClientFactory from twisted.internet.endpoints import clientFromString from twisted.internet import reactor class EchoClientProtocol(Protocol): def connectionMade(self): self.transport.write('> To Server:Hello server'); def dataReceived(self, data): print('> From Server:%s' % data) reactor.stop() class EchoClientFactory(ClientFactory): protocol = EchoClientProtocol if __name__ == '__main__': #construct 10 client endpoints for i in xrange(10): clientFromString(reactor,'tcp:localhost:8888') .connect( EchoClientFactory() ) reactor.run()
echo_server.py
from twisted.internet.protocol import Protocol,Factory from twisted.internet import reactor from twisted.internet.endpoints import serverFromString class EchoServerProtocol(Protocol): def connectionMade(self): print('> New connection made,from client!') self.factory.conn = self.factory.conn + 1 print('> Now conn=%d' % self.factory.conn) def dataReceived(self, data): print('> Data from client: %s'% data) self.transport.write(data) print('>Host: ',repr(self.transport.getHost())) print('>Peer: ',repr(self.transport.getPeer())) #Close connection with client self.transport.loseConnection() self.factory.conn = self.factory.conn - 1 class EchoServerFactory(Factory): protocol = EchoServerProtocol def __init__(self): self.conn = 0 if __name__ == '__main__': serverFromString(reactor,'tcp:8888'). listen( EchoServerFactory() ) reactor.run()
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-04 17:00:41