twisted介绍与用户端服务器端

这里写图片描述

摘要:介绍twisted是什么,分析一下编程的三个经典模型,说明twisted
走的是异步编程的路线,了解一下twisted的构成及reactor模式;参考官网编写twisted简单的例子,也是用来入门的,一个服务器端,一个客户端。

1.twisted是什么

Twisted is an event-driven networking engine written in Python;
Twisted 是一个用python写的基于事件驱动的网络引擎。
Event-driven programming is a programming paradigm in which program flow is determined by external events. It is characterized by an event loop and the use of callbacks to trigger actions when events happen. Two other common programming paradigms are (single-threaded) synchronous and multi-threaded programming.
事件驱动编程是一个编程范式, 这个程序是由外部事件来决定。通过事件循环及当事件发生时触发回调事件的使用是它的特点。另外两种常见的编程范式是(单线程)同步与多线程编程。

2.相关的编程模型

三种编程范式对比:single-threaded, multi-threaded, event-driven programming models,下面的灰色表示进程对IO请求的等待时长。图片来自【1】
这里写图片描述
引用【3】对这三个区别的解说:

single-threaded:
表示了串行的程序执行方式,所有任务都必须按顺序进行,有一个缺点,如果这三个任务不存在依赖关系,这样的效率就很低了。

在multi-threaded版本中,这3个任务分别在独立的线程中执行。这些线程由操作系统来管理,在多处理器系统上可以并行处理,或者在单处理器系统上交错执行。这使得当某个线程阻塞在某个资源的同时其他线程得以继续执行。与完成类似功能的同步程序相比,这种方式更有效率,但程序员必须写代码来保护共享资源,防止其被多个线程同时访问。多线程程序更加难以推断,因为这类程序不得不通过线程同步机制如锁、可重入函数、线程局部存储或者其他机制来处理线程安全问题,如果实现不当就会导致出现微妙且令人痛不欲生的bug。

在event-driven programming models中,3个任务交错执行,但仍然在一个单独的线程控制中。当处理I/O或者其他昂贵的操作时,注册一个回调到事件循环中,然后当I/O操作完成时继续执行。回调描述了该如何处理某个事件。事件循环轮询所有的事件,当事件到来时将它们分配给等待处理事件的回调函数。这种方式让程序尽可能的得以执行而不需要用到额外的线程。事件驱动型程序比多线程程序更容易推断出行为,因为程序员不需要关心线程安全问题。

3.twisted构成

twisted网络框架的三个基础模块:Protocol, ProtocolFactory, Transport.这三个模块是构成twisted服务器端与客户端程序的基本。
Protocol:Protocol对象实现协议内容,即通信的内容协议
ProtocolFactory: 是工厂模式的体现,在这里面生成协议
Transport: 是用来收发数据,服务器端与客户端的数据收发与处理都是基于这个模块;

4. reactor

Twisted实现了设计模式中的反应堆(reactor)模式,这种模式在单线程环境中调度多个事件源产生的事件到它们各自的事件处理例程中去。Reactor可以感知网络、文件系统以及定时器事件。
回调是事件驱动编程模型中的基础,也是reactor通知应用程序事件已经处理完成的方式。
具体的可参见【4】,twisted在实现reactor时,与平台有关的,当是linux等平台,安装了epoll等,会用这个启动。可以了解一下多路IO复用,sellect、poll、epoll三者的区别【5】。
下面是在win7上调试的,选择了select来实现reactor模式。

来自文件:site-packages\twisted\internet\reactor.py

import sys
del sys.modules['twisted.internet.reactor']
from twisted.internet import default
default.install()

site-packages\twisted\internet\default.py
try:
    if platform.isLinux():
        try:
            from twisted.internet.epollreactor import install
        except ImportError:
            from twisted.internet.pollreactor import install
    elif platform.getType() == 'posix' and not platform.isMacOSX():
        from twisted.internet.pollreactor import install
    else:
        from twisted.internet.selectreactor import install
except ImportError:
    from twisted.internet.selectreactor import install
return install

导入reactor是根据不同的平台,实时安装不同的模块的。
对于windows,site-packages\twisted\internet\selectreactor.py

def install():
    # Configure the twisted mainloop to be run using the select() reactor.

    reactor = SelectReactor()
    from twisted.internet.main import installReactor
    installReactor(reactor)

调试时也会看到:
<twisted.internet.selectreactor.SelectReactor object at 0x0000000004031908>
这里写图片描述

参考官网入门代码【2】,修改与增加注解,写了两个文件,一个是客户端,一个是服务器端。

5. 实现自己的类

MyProtocol类
这里写图片描述

Factory类
这里写图片描述

6. 服务器端

# coding=utf-8
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, Factory


class MyProtocol(Protocol):
    def connectionMade(self):
        print('来自(%s,%s)连接' % self.transport.client)

    def connectionLost(self, reason):
        print('释放(%s:%s)连接' % (self.transport.client))

    def dataReceived(self, data):
        s_data = str(data, encoding='utf-8')
        print(u'发来的信息:\n%s' % s_data)


if __name__ == '__main__':
    # 创建一个protocol工厂
    factory = Factory()
    # 指向我的数据格式
    factory.protocol = MyProtocol
    # 启动服务,listenTCP是来自posixbase类的
    info = reactor.listenTCP(9999, factory)
    print('%s start...' % (info.port))
    # 运行,这个方法是来自_SignalReactorMixin类的,这个类是管理信号的
    reactor.run()

7.客户端

# coding=utf-8
from socket import *

if __name__ == '__main__':
    s = socket(AF_INET, SOCK_STREAM)
    remote_host = gethostname()
    s.connect((remote_host, 9999))
    print("建立连接:", (s.getsockname(), '--->', s.getpeername()))

    s.send(bytes('i am happyprince form client\n', encoding="utf8"))
    s.send(bytes(u'我是来自客户端的快乐王子。', encoding='utf-8'))

8.运行结果

服务器端
这里写图片描述
客户端
这里写图片描述

9.参考

【1】http://www.aosabook.org/en/twisted.html
【2】twisted官网:http://twistedmatrix.com/documents/current/core/examples/index.html
【3】https://www.cnblogs.com/lixiaoliuer/p/6728789.html
【4】 Reactor模式详解
http://www.blogjava.net/DLevin/archive/2015/09/02/427045.html
【5】python select网络编程详细介绍
https://www.cnblogs.com/lxmhhy/p/6091730.html

【作者:happyprince, http://blog.csdn.net/ld326/article/details/78761227

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值