Twisted是用Python实现的基于事件驱动的网络引擎框架,功能非常丰富,基本包括了常用的网络组件。

所谓事件驱动,就是说程序就像是一个报警器(reactor),时刻等待着外部事件(event),诸如有人入侵等,一旦有事件发生,程序就会触发一些特定的操作(callback),注入拨打报警电话等。

Reactor

reactor是twisted框架中的核心,负责管理各种回调函数,接收各种系统事件,并根据规则对事件和回调函数进行匹配、派发处理。在Linux系统中,由于秉承“一切皆文件”的理念,系统中的事件主要就是文件事件以及定时事件。其实大多使用了不同系统中特定的API,具体来说,Linux上默认是epoll,OS X默认是Poll,其他系统默认都是select,每个API都会有一个特定的reactor与之对应。

从代码上来看,每当你import twisted.internet.reactor时,他就会根据当前系统返回特定的reactor module(twisted/twisted/internet/default.py),然后调用特定reactor module的install()函数。这里我们看一下对应Linux系统的epollreactor的install函数

# twisted/twisted/internet/epollreactor.py

def install():
"""
Install the epoll() reactor.
"""
p = EPollReactor()
from twisted.internet.main import installReactor
installReactor(p) #twisted/twisted/intenet/main.py def installReactor(reactor):
"""
Install reactor C{reactor}. @param reactor: An object that provides one or more IReactor* interfaces.
"""
# this stuff should be common to all reactors.
import twisted.internet
import sys
if 'twisted.internet.reactor' in sys.modules:
raise error.ReactorAlreadyInstalledError("reactor already installed")
twisted.internet.reactor = reactor
sys.modules['twisted.internet.reactor'] = reactor

代码是非常清楚的,就是创建了一个EPollReactor的实例,然后使用sys.module[""] = reactor将其注册为默认的reactor,这也就是使用twisted编程时不需显示创建reactor的原因。

究竟一个reactor到底干了些什么呢?twisted在这一块为了抽象以及扩展性,写了大量的类,用了大量的继承,但是简单来说,最终会落回到EPollReactor的doPoll函数中。

def doPoll(self, timeout):
"""
Poll the poller for new events.
"""
if timeout is None:
timeout = -1 # Wait indefinitely. try:
# Limit the number of events to the number of io objects we're
# currently tracking (because that's maybe a good heuristic) and
# the amount of time we block to the value specified by our
# caller.
l = self._poller.poll(timeout, len(self._selectables))
except IOError as err:
if err.errno == errno.EINTR:
return
# See epoll_wait(2) for documentation on the other conditions
# under which this can fail. They can only be due to a serious
# programming error on our part, so let's just announce them
# loudly.
raise _drdw = self._doReadOrWrite
for fd, event in l:
try:
selectable = self._selectables[fd]
except KeyError:
pass
else:
log.callWithLogger(selectable, _drdw, selectable, fd, event)

  其中的self._poller通过epoll就是一个epoll调用的返回值,简单点说,也就是一个典型的epoll应用场景,在timeout时间内,检查需要处理的事件,然后通过log.callWithLogger调用相关的回调函数。

Transport

用于抽象通信双方之间的链接(TCP、UDP等),通过它可以向对方发送数据,获取对方信息等。

Protocol

用于抽象双方的通信协议,包括如何建立链接、处理数据以及出错处理等接口。一个类实现了这些接口,就等于定义了一个新的协议,twisted自带的协议非常多,一般情况下不需要自定义协议,除非你有特殊要求。

Protocol Factory

熟悉设计模式的应该对factory不陌生,简单来说,这个类定义了一个接口buildProtocol,用于返回一个Protocl实例(但是通常的做法是在factory类中使用类成员protocol来注册响应的Protocol),同时在这个类里你可以保存一些数据,用于配置或者管理系统中所有的Protocol实例。

简单的Echo服务器程序

# Server
from twisted.internet import protocol, reactor class Echo(protocol.Protocol):
def dataReceived(self, data):
self.transport.write(data) class EchoFactory(protocol.Factory):
def buildProtocol(self, addr):
return Echo() reactor.listenTCP(8080, EchoFactory())
reactor.run() # Client
from twisted.internet import protocol, reactor class EchoClient(protocol.Protocol):
def connectionMade(self):
self.transport.write("Hello, world!") def dataReceived(self, data):
self.transport.loseConnection() class EchoFactory(protocol.ClientFactory):
def buildProtocol(self, addr):
return EchoClient() def clientConnectionFailed(self, connector, reason):
reactor.stop() def clientConnectionLost(self, connector, reason):
reactor.stop() reactor.connectTCP("localhost", 8080, EchoFactory())
reactor.run()

  

  

Twisted网络编程入门的更多相关文章

  1. 脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?

    本文引用了“帅地”发表于公众号苦逼的码农的技术分享. 1.引言 搞网络通信应用开发的程序员,可能会经常听到外网IP(即互联网IP地址)和内网IP(即局域网IP地址),但他们的区别是什么?又有什么关系呢 ...

  2. 脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?

    本文引用了公众号纯洁的微笑作者奎哥的技术文章,感谢原作者的分享. 1.前言   老于网络编程熟手来说,在测试和部署网络通信应用(比如IM聊天.实时音视频等)时,如果发现网络连接超时,第一时间想到的就是 ...

  3. 脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)

    本文原作者阮一峰,作者博客:ruanyifeng.com. 1.前言 新一代HTTP/2 协议的主要目的是为了提高网页性能(有关HTTP/2的介绍,请见<从HTTP/0.9到HTTP/2:一文读 ...

  4. 脑残式网络编程入门(三):HTTP协议必知必会的一些知识

    本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...

  5. 脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

    1.引言 本文接上篇<脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手>,继续脑残式的网络编程知识学习 ^_^. 套接字socket是大多数程序员都非常熟悉的概念,它是计算机 ...

  6. 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    .引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方 ...

  7. [转帖]脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?

    脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?     http://www.52im.net/thread-1732-1-1.html   1.引言 本文接上篇<脑残式网 ...

  8. [转帖]脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手   http://www.52im.net/thread-1729-1-1.html     1.引言 网络编程中TCP协议的三次握手和 ...

  9. JAVA网络编程入门

    JAVA网络编程入门 软件结构 C/S结构 B/S结构 无论哪一种结构,都离不开网络的支持.网络编程,就是在网络的条件下实现机器间的通信的过程 网络通信协议 网络通信协议:通信双方必须同时遵守才能完成 ...

随机推荐

  1. JQuery 公网 CDN

    JQuery 公网 CDN   <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.4.min.js&quo ...

  2. c++学习笔记——聚合类

    聚合类定义:1.所有的成员都是public的. 2.没有定义任何构造函数. 3.没有类内初始值. 4.没有基类,也没有virtual函数. 聚合类的初始化:我们可以提供一个花括号括起来的成员函数初始值 ...

  3. Net分布式系统之二:CentOS系统搭建Nginx负载均衡(下)

    上一篇文章介绍了VMWare12虚拟机.Linux(CentOS7)系统安装.部署Nginx1.6.3代理服务做负载均衡.接下来介绍通过Nginx将请求分发到各web应用处理服务. 一.Web应用开发 ...

  4. codevs 2756树上的路径

    题意: 2756 树上的路径  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master    题目描述 Description 给出一棵树,求出最小的k,使得,且在树 ...

  5. 《机器学习实战》学习笔记——第14章 利用SVD简化数据

    一. SVD 1. 基本概念: (1)定义:提取信息的方法:奇异值分解Singular Value Decomposition(SVD) (2)优点:简化数据, 去除噪声,提高算法的结果 (3)缺点: ...

  6. 对div作用域的理解

    若想要div的height起作用,则要保证它上面的层的height也是有用的,如上图

  7. SQL数据库完全复制

    很少摸 Windows 环境下的东西,最近被个 MS SQL Server 的数据库搞得头大.实在不像 MySQL 那样用起来轻车熟路, OrZ ... 本来以为企业管理器里面既然提供了 DTS 数据 ...

  8. 前端开发必备! 20 个强大的 Sublime Text 插件

    http://www.oschina.net/translate/20-powerful-sublimetext-plugins http://www.w3cplus.com/tools/emmet- ...

  9. RTX2010服务器端的主要通信端口有哪些?

    RTX服务端程序在安装之后,如果安装服务端电脑的操作系统有防火墙(如Windows XP.Windows2003等)或者安装了防火墙(如瑞星.Norton等),那么需要在防火墙上打开RTX所需要使用的 ...

  10. unity3d使用脚本保存屏幕截图

    using UnityEngine; using System.Collections; using System.IO; public class FrameAnimation : MonoBeha ...