一、基本概念
Twisted 定义:
Twisted 是用 Python 实现的基于事件驱动的网络引擎框架。具有以下特点:
-- 可扩展性高、基于事件驱动、跨平台。
--Twisted 支持许多常见的传输及应用层协议,如:TCP、UDP、SSL/TLS、HTTP、IMAP、SSH、IRC以及FTP。
--Twisted 对于其支持的所有协议都带有客户端和服务器的实现
二、Twisted架构
设计哲学
Twisted 是一个事件驱动型的网络引擎。事件驱动编程是一种编程范式,这里程序的执行流由外部事件来决定。它的特点是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的处理模型图比较
单线程、多线程以及事件驱动编程模型的比较
注:其中灰色部分为每个任务阻塞在I/O操作上所花的 时间
从上图可以看出:
单线程
在单线程同步模型中,任务按照顺序执行。如果某个任务因为 I/O 而阻塞,其他所有的任务都必须等待,直到它完成之后它们才能依次执行。多线程
线程由操作系统来管理,在多处理器系统上可以并行处理,或者在单处理器系统上交错执行。这使得当某个线程阻塞在某个资源的同时其他线程得以继续执行。但多线程程序难以推断,如果实现不当就会导致出现微妙且令人痛不欲生的 bug。事件驱动
多个任务交错执行,但仍然在一个单独的线程中控制通过事件循环轮询每个事件。不需要关心线程安全问题
三、实例呈现
(1)服务器的实现
Server.py
# coding=utf-8
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, Factory
class SimpleProtocol(Protocol):
def connectionMade(self):
"""客户端连入后向客户端发送一条消息Hello"""
print 'success from ', self.transport.client
self.transport.write("Hello")
def connectionLost(self, reason):
print self.transport.client, 'disconnected'
print reason
def dataReceived(self, data):
print data
factory = Factory()
factory.protocol = SimpleProtocol
# 在9001端口进行监听
reactor.listenTCP(9001, factory)
# 启动事件循环
reactor.run()
其中SimpleProtocol是我复写的一个Protocol.
(2)客户端的实现
connection.py
# coding=utf-8
from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet import reactor
class Sender(Protocol):
def connectionMade(self):
"""连接成功后调用"""
self.send_command()
def send_command(self):
"""连接成功后调用他向服务端发送数据"""
self.transport.write("hello")
def dataReceived(self, data):
"""进行数据的接受"""
print "DATA", data
class BasicClientFactory(ClientFactory):
def __init__(self, protocol):
self.protocol = protocol
def clientConnectionLost(self, connector, reason):
print 'Lost connection: %s' % reason.getErrorMessage()
PORT = 9001
HOST = '127.0.0.1'
# 实例化工厂对象
test = BasicClientFactory(Sender)
# 连接服务器
reactor.connectTCP(HOST, PORT, test)
reactor.run()
注:我复写了客户端所需要的工厂ClientFactory
(3)运行测试
先在终端上运行Server.py等待客户端的连入,然后重新开一个终端运行connection.py连接服务器。
会看到客户端和服务端各自收到了一条来自对方的hello的问候消息(如下图所示)。
四、代码原理剖析
(1)
Factory:
每个服务器与客户端都会有一个工厂。他负责创建连接。并创建 protocol 对象。Protocols:
Protocols 描述了如何以异步的方式处理网络中的事件。当连接创建成功后,Factory 会创建一个 protocol, 由 protocol 进行通信。Transports
Transports 代表网络中两个通信结点之间的连接。Transports负责描述连接的细节,
比如连接是面向流式的还是面向数据报的,流控以及可靠性。
(2)
-
Transports 实现了 ITransports 接口,它包含如下的方法:
-- write方法: 以非阻塞的方式按顺序依次将数据写到物理连接上。
-- writeSequence方法: 将一个字符串列表写到物理连接上。
-- loseConnection 方法:将所有挂起的数据写入,然后关闭连接。
-- getPeer方法: 取得连接中对端的地址信息。
-- getHost方法: 取得连接中本端的地址信息。 Protocols 实现了 IProtocol 接口,它包含如下的方法:
-- makeConnection方法: 在 transport 对象和服务器之间建立一条连接。
-- connectionMade方法: 连接建立起来后调用。
-- dataReceived方法: 接收数据时调用。
-- connectionLost方法: 关闭连接时调用。
(3)
- Reactor 模式:
Twisted 实现了设计模式中的反应堆(reactor)模式,这种模式在单线程环境中调度多个事件源产生的事件到它们各自的事件处理例程中去。Twisted 的核心就是 reactor 事件循环。Reactor 可以感知网络、文件系统以及定时器事件。它等待然后处理这些事件。
温馨提示:
Twisted 没有直接发送数据的函数,发送数据通过Transports 中的 write 进行数据的发送。