简单使用
Twisted是用Python实现的基于事件驱动的网络引 擎框架,Twisted支持许多常见的传输及应用层协议,包括TCP、UDP、SSL/TLS、HTTP、IMAP、SSH、IRC以及FTP。就像Python一样,Twisted也具有“内置电池”(batteries-included)的特点。Twisted对于其支持的所有协议都带有客户端和服务 器实现,同时附带有基于命令行的工具,使得配置和部署产品级的Twisted应用变得非常方便。
内部方法介绍
Transports
Transports代表网络中两个通信结点之间的连接。Transports负责描述连接的细节,比如连接是面向流式的还是面向数据报的,流控以及可靠性。TCP、UDP和Unix套接字可作为transports的例子。它们被设计为“满足最小功能单元,同时具有最大程度的可复用性”,而且从协议实现中分离出来,这让许多协议可以采用相同类型的传输。Transports实现了ITransports接口,它包含如下的方法: write 以非阻塞的方式按顺序依次将数据写到物理连接上 writeSequence 将一个字符串列表写到物理连接上 loseConnection 将所有挂起的数据写入,然后关闭连接 getPeer 取得连接中对端的地址信息 getHost 取得连接中本端的地址信息 getPage 发送HTTP请求 将transports从协议中分离出来也使得对这两个层次的测试变得更加简单。可以通过简单地写入一个字符串来模拟传输,用这种方式来检查。
Protocols
Protocols描述了如何以异步的方式处理网络中的事件。HTTP、DNS以及IMAP是应用层协议中的例子。Protocols实现了IProtocol接口,它包含如下的方法: makeConnection 在transport对象和服务 器之间建立一条连接 connectionMade 连接建立起来后调用 dataReceived 接收数据时调用 connectionLost 关闭连接时调用
Reactor模式
Twisted实现了设计模式中的反应堆(reactor)模式,这种模式在单线程环境中调度多个事件源产生的事件到它们各自的事件处理例程中去。 Twisted的核心就是reactor事件循环。Reactor可以感知网络、文件系统以及定时器事件。它等待然后处理这些事件,从特定于平台的行为中抽象出来,并提供统一的接口,使得在网络协议栈的任何位置对事件做出响应都变得简单。
Deferreds
Deferred对象以抽象化的方式表达了一种思想,即结果还尚不存在。它同样能够帮助管理产生这个结果所需要的回调链。当从函数中返回时,Deferred对象承诺在某个时刻函数将产生一个结果。返回的Deferred对象中包含所有注册到事件上的回调引用,因此在函数间只需要传递这一个对象即可,跟踪这个对象比单独管理所有的回调要简单的多。 Deferred对象包含一对回调链,一个是针对操作成功的回调,一个是针对操作失败的回调。初始状态下Deferred对象的两条链都为空。在事件处理的过程中,每个阶段都为其添加处理成功的回调和处理失败的回调。当一个异步结果到来时,Deferred对象就被“激活”,那么处理成功的回调和处理失败的回调就可以以合适的方式按照它们添加进来的顺序依次得到调用。
简单的使用
一、服务 器代码编写
from twisted
.internet
import protocol
, reactor
from twisted
.internet
.endpoints
import TCP4ServerEndpoint
from time
import ctime
class TSServerProtocol(protocol
.Protocol
):
"""
服务器端协议
每一个客户端连接对应一个实例。
"""
def __init__(self
):
self
.clientInfo
= ""
def connectionMade(self
):
self
.clientInfo
= self
.transport
.getPeer
()
print("来自%s的连接" % (self
.clientInfo
))
def dataReceived(self
, data
):
recData
= data
.decode
()
print("收到来自%s的数据:%s" % (self
.clientInfo
, recData
))
rep
= '[%s] %s' % (ctime
(), recData
)
self
.transport
.write
(rep
.encode
())
class TSServerFactory(protocol
.Factory
):
def buildProtocol(self
, addr
):
return TSServerProtocol
()
endpoint
= TCP4ServerEndpoint
(reactor
, PORT
)
endpoint
.listen
(TSServerFactory
())
print("等待客户端连接")
reactor
.run
()
二、客户端代码的编写
from twisted
.internet
import protocol
, reactor
class TSClientProtocol(protocol
.Protocol
):
def sendData(self
):
data
= input("> ")
if data
:
self
.transport
.write
(data
.encode
())
else:
self
.transport
.loseConnection
()
def connectionMade(self
):
self
.sendData
()
def dataReceived(self
, data
):
recData
= data
.decode
()
print("从服务器上收到的数据:%s" % (recData
))
self
.sendData
()
class TSClientFactory(protocol
.ClientFactory
):
protocol
= TSClientProtocol
clientConnectionLost
= clientConnectionFailed
= lambda self
, connector
, reason
:reactor
.stop
()
reactor
.connectTCP
(HOST
, PORT
, TSClientFactory
())
reactor
.run
()
三、getPage的使用
from twisted
.internet
import defer
from twisted
.web
.client
import getPage
from twisted
.internet
import reactor
def one_done(arg
):
print(arg
)
def all_done(arg
):
print('done')
reactor
.stop
()
@defer
.inlineCallbacks
def task(url
):
res
= getPage
(bytes(url
, encoding
='utf8'))
res
.addCallback
(one_done
)
yield res
url_list
= [
'http://www.baidu.com',
'http://www.so.com',
'http://www.sogou.com',
]
defer_list
= []
for url
in url_list
:
v
= task
(url
)
defer_list
.append
(v
)
d
= defer
.DeferredList
(defer_list
)
d
.addBoth
(all_done
)