Twisted网络编程入门
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网络编程入门的更多相关文章
- 脑残式网络编程入门(六):什么是公网IP和内网IP?NAT转换又是什么鬼?
本文引用了“帅地”发表于公众号苦逼的码农的技术分享. 1.引言 搞网络通信应用开发的程序员,可能会经常听到外网IP(即互联网IP地址)和内网IP(即局域网IP地址),但他们的区别是什么?又有什么关系呢 ...
- 脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?
本文引用了公众号纯洁的微笑作者奎哥的技术文章,感谢原作者的分享. 1.前言 老于网络编程熟手来说,在测试和部署网络通信应用(比如IM聊天.实时音视频等)时,如果发现网络连接超时,第一时间想到的就是 ...
- 脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)
本文原作者阮一峰,作者博客:ruanyifeng.com. 1.前言 新一代HTTP/2 协议的主要目的是为了提高网页性能(有关HTTP/2的介绍,请见<从HTTP/0.9到HTTP/2:一文读 ...
- 脑残式网络编程入门(三):HTTP协议必知必会的一些知识
本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...
- 脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?
1.引言 本文接上篇<脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手>,继续脑残式的网络编程知识学习 ^_^. 套接字socket是大多数程序员都非常熟悉的概念,它是计算机 ...
- 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手
.引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方 ...
- [转帖]脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?
脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么? http://www.52im.net/thread-1732-1-1.html 1.引言 本文接上篇<脑残式网 ...
- [转帖]脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手
脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手 http://www.52im.net/thread-1729-1-1.html 1.引言 网络编程中TCP协议的三次握手和 ...
- JAVA网络编程入门
JAVA网络编程入门 软件结构 C/S结构 B/S结构 无论哪一种结构,都离不开网络的支持.网络编程,就是在网络的条件下实现机器间的通信的过程 网络通信协议 网络通信协议:通信双方必须同时遵守才能完成 ...
随机推荐
- 初识Memcached
一,什么是memcached? Memcached是一个高性能的分布式内存对象缓存系统,用于动态web应用以减轻数据库负载..它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱 ...
- 8.10 CSS知识点3
7.属性选择符 选择符 版本 描述 E[att] CSS2 选择具有att属性的E元素 E[att="val"] CSS2 选择具有att属性值等于val的E元素 E[att~=& ...
- sql良好习惯
我们做软件开发的,大部分人都离不开跟数据库打交道,特别是erp开发的,跟数据库打交道更是频繁,存储过程动不动就是上千行,如果数据量大,人员流动大,那么我么还能保证下一段时间系统还能流畅的运行吗?我么还 ...
- HttpURLConnection 下载文件
String fileUrl = request.getRequestURL().substring(0, request.getRequestURL().indexOf("/rest&qu ...
- eval语句(sql)类似asp
执行字符串的SQL语句,相当于asp中的eval ***** declare @sql nvarchar(500) set @sql='select * from sk_hzp_fk_prescri ...
- Spring配置数据源的几种形式
Spring中提供了4种不同形式的数据源配置方式: 1.Spring自带的数据源(DriverMangerDataSource); 2.DBCP数据源; 3.C3P0数据源; 4.JNDI数据源. 以 ...
- WINDOWS的NTP配置
将下面内容复制到记事本,保存成ntp.bat net stop w32Time REG ADD HKLM\SYSTEM\CurrentControlSet\Services\W32Time\TimeP ...
- Android消息机制:Looper,MessageQueue,Message与handler
Android消息机制好多人都讲过,但是自己去翻源码的时候才能明白. 今天试着讲一下,因为目标是讲清楚整体逻辑,所以不追究细节. Message是消息机制的核心,所以从Message讲起. 1.Mes ...
- js取最小最大值--Math.min()、math.max()
一.Math.min() 返回一组表达式中最小者 eg: var n = Math.min( 2 , 30 ,1 , 200-10 , 300*22 , 20-30 ); alert(n); //打印 ...
- 网站加载css/js/img等静态文件失败
网站加载css/js/img等静态文件失败,报网站http服务器内部500错误.而服务器中静态文件存在且权限正常. 从浏览器中直接访问文件,出来乱码.这种问题原因在于iis中该网站mime配置报错,不 ...