热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Twisted网络编程必备(1)注:测试版本Twisted10.1.0.winxp32py2.6,对于原代码略有修改

转自:http:www.yybug.comread-htm-tid-15324.html为什么使用Twisted? 如果你并不准备使用Twisted,你可能有很多异议。为什么使用T





转自:http://www.yybug.com/read-htm-tid-15324.html


为什么使用Twisted?


 


如果你并不准备使用Twisted,你可能有很多异议。为什么使用Twisted而不是其他网络函数库或框架?如下是一些充分的理由:


·基于Python


Twisted是使用Python编写的,强壮的、面向对象的解释性语言。Python使它的爱好者充满热情。使用Python编程是一种乐趣,易于编写、易于阅读、易于运行。因为Python是跨平台的,所以可以运行Twisted程序在Linux、Windows、Unix和MAC等等系统上。


·异步和事件驱动的


同步网络编程函数库留给开发者一个痛苦的抉择:要么允许程序在网络通信时失去响应,或者引入非常复杂的线程。Twisted是基于事件的,异步网络通信框架允许编写的程序在处理事件时保持相应,却不需要使用线程。


·多功能


Twisted包括大量的功能。Email、WEB、news、chat、DNS、SSH、Telnet、RPC、数据库存取或者更多。所有的都为你准备好了。


·灵活


Twisted提供了高层类允许快速开始。而且并没有感到受限。如果需要高级功能,或者需要自定义网络协议,也是可以的。你可以实现自己的网络协议,控制每一个字节。


·开放源代码


Twisted是免费的。它包含源代码,按照函数库协议发行。并且欢迎在你的程序中使用Twisted,不必支付任何费用和担心法律问题。如果希望知道一个对象的运行原理也可以直接看源码。如果你开发出了自己的新功能和扩展,欢迎与我们共享。


·社区支持


Twisted有一个活跃的社区包含开发者和用户。如果你发现了问题,也可以在邮件列表上找到很多开发者来帮助你。查看第一章的寻找FAQ一节。或者进入#twisted这个IRC频道,来与开发者进行在线交流。


·易于整合的平台


一个Twisted程序可以在多种服务之间共享数据,可以整合很多工作。比如可以编写SMTP到XMLRPC的代理,一个通过SSH来更新网站的服务,或者一个包含NNTP接口的WEB讨论组。如果需要在平台之间交换数据,Twisted是个很好的选择。


 


启动Twisted的事件循环


Twisted是事件驱动的框架。这意味着不再使用特定序列来处理程序逻辑,而是通过被动调用一些函数来实现。例如,GUI程序里面使用的"button pressed"事件。设计者不需要事先确定事件何时发生,只需要编写事件的响应函数即可。这就是所谓的事件处理器(event handler)。


 


每个事件驱动的框架都包含了一个特殊的函数叫做事件循环(event loop)。每次启动,事件循环都会立即运行。这个函数运行时等待事件的发生。当事件发生时,事件循环函数会自动触发相关的事件处理函数。


使用事件循环需要改变一些顺序编程的习惯。一旦开始了事件循环,你将无法控制程序的执行顺序,只会自动响应事件。所以,你需要为程序设计事件处理器。也就是事件发生时的响应。


在Twisted中,有一种特殊的对象用于实现事件循环。这个对象叫做reactor。可以把反应器(reactor)想象为Twisted程序的中枢神经。除了分发事件循环之外,反应器还做很多重要的工作:定时任务、线程、建立网络连接、监听连接。为了让反应器可以正常工作,需要启动事件循环


 


启动反应器


 


启动反应器是很简单的,从twisted.internet模块导入reactor对象。然后调用reactor.run()来启动反应器的事件循环。下例展示了代码:




from twisted.internet.selectreactor import SelectReactor
print 'Running the reactor ...'
reactor = SelectReactor()
reactor.run()
print 'Reactor stopped.'


 


反应器将会一直运行,直到接到停止的通知,可以按下Ctrl+C来退出事件循环,并终止程序:




$ python runreactor.py
Running the reactor ...
<ctrl-c>
^CReactor stopped.


 


这是一个简洁的例子。尽管反应器运行着,但是没有做任何事情。下面的例子提供了更多有趣的事情,介绍了反应器的callLater方法。reactor.callLater方法用于设置定时事件。这个方法在用于定时在未来执行。比如一个函数已经是一个事件处理器了,这种事件会在一定时间之后启动。下面的例子,函数调用了一定时间之后被调用:


 



代码


from twisted.internet.selectreactor import SelectReactor
import time
reactor = SelectReactor()
def printTime():
print 'Current time is',time.strftime("%H:%M:%S")
def stopReactor():
print "Stopping reactor"
reactor.stop()
reactor.callLater(
1,printTime)
reactor.callLater(
2,printTime)
reactor.callLater(
3,printTime)
reactor.callLater(
4,printTime)
reactor.callLater(
5,stopReactor)
print 'Running the reactor ...'
reactor.run()
print 'Reactor stopped.'



 


运行这个程序,可以看到如下结果:


$ python calllater.py


Running the reactor ...


Current time is 10:33:44


Current time is 10:33:45


Current time is 10:33:46


Current time is 10:33:47


Stopping reactor


Reactor stopped.


 


它是如何工作的


 


第一个例子简介了导入与执行reactor.run()来启动事件循环。反应器将会一直保持执行直到按下Ctrl-C,尽管这一段时间什么都不做。在这时,反应器停止了,程序执行到代码的最后一行,并打印出反应器已经停止的消息。


第二个例子使用reactor.callLater函数定时执行函数。reactor.callLater函数包含两个必须参数,等待的秒数,和需要调用的函数。在设置了定时函数调用之后,控制就回到了反应器的事件循环reactor.run()中了。


Tip:你可以传递附加的参数和键值对到reactor.callLater中,这些用于调用指定的函数。例如,reactor.callLater(1,func,True,x="Hello"),将会最终调用func(True,x="Hello"),在一秒钟之后。


第一个定时函数是printTime(),简单显示了当前时间。第五个定时函数是stopReactor(),其中调用了reactor.stop(),导致了反应器退出了事件循环。这也是为什么不需要按下Ctrl-C而自动退出了事件循环的原因。


Tip:在这种情况下仍然可以按下Ctrl-C来手动停止事件循环。


注意事件的发生顺序,反应器按照给定的时间来调用指定的函数。一旦反应器开始运行,反应器就会控制事件循环,并在指定时间调用函数。反应器在被告知停止之前会一直运行,直到reactor.stop()调用。一旦反应器停止了,程序将继续处理最后一行,显示反应器停止的消息。


Tip:在实际应用中,reactor.callLater是常用于超时处理和定时事件。可以设置函数按照指定的时间间隔来执行关闭非活动连接或者保存内存数据到硬盘。


 


建立(establishing)一个TCP连接


 


所有的网络应用程序都必须做一个简单的步骤,开启一个连接。接着可以发送邮件、传递文件、看电影等等,但是在所有这些之前,必须在电脑之间建立一个连接。本节讲解了如何使用reactor开启TCP连接。


 


调用reactor.connectTCP()方法打开一个TCP连接,传递一个ClientFactory对象作为第三个参数。ClientFactory对象等待连接被建立,然后创建一个Protocol对象来管理连接中的数据流。下面的例子展示了如何在电脑和Internet之间建立一个连接(www.google.com):





代码


from twisted.internet.selectreactor import SelectReactor
from twisted.internet.protocol import Protocol,ClientFactory
reactor
= SelectReactor()
protocol
= Protocol()
class QuickDisconnectedProtocol(Protocol):
def connectionMade(self):
print "Connected to %s."%self.transport.getPeer().host
self.transport.loseConnection()
class BasicClientFactory(ClientFactory):
protocol
=QuickDisconnectedProtocol
def clientConnectionLost(self,connector,reason):
print 'Lost connection: %s'%reason.getErrorMessage()
reactor.stop()
def clientConnectionFailed(self,connector,reason):
print 'Connection failed: %s'%reason.getErrorMessage()
reactor.stop()
reactor.connectTCP(
'www.google.com',80,BasicClientFactory())
reactor.run()




 



 


当运行这个例子的时候,可以看到如下输出:


$ python connection.py


Connected to 66.249.89.104.
Lost connection: Connection was closed cleanly.


除非你的电脑没有在线。在这种情况下,会看到如下错误信息:


$ python connection.py


Connection failed: DNS lookup failed: address 'www.google.com' not found.


 


它是如何工作的


 


这里有两个主要的类用于作为客户端工作,ClientFactory和Protocol。这些类被设计成处理连接中所有可能运到的事件:成功建立连接、连接失败、连接断开、数据传送等等。


ClientFactory和Protocol有严格的不同。ClientFactory的工作是管理连接事件并且创建Protocol对象处理每一个成功的连接。一旦连接建立,Protocol对象就接管下面的工作了,包括收发数据和决定是否关闭连接。


Tip:名字"Factory"在ClientFactory是来自于Protocol的请求,响应每一个成功的连接。


例子定义了自定义的Protocol叫做QuickDisconnectProtocol,继承自protocol.Protocol。它重载了一个方法connectMade。这个方法连接成功时运行,在reactor刚刚成功建立了连接,然后ClientFactory创建了QuickDisconnectProtocol的实例时。有如他的名字,QuickDisconnectProtocol对象在打印信息之后就马上关闭了。


Tip:Protocol对象有一个属性叫做transport,包含了当前活动连接对象。


BasicClientFactory是继承自protocol.ClientFactory的类。它首先设置了类变量protocol为QuickDisconnectProtocol。这个类的实例被创建用于管理成功的连接。


BasicClientFactory重载了ClientFactory的两个方法,clientConnectionLost和clientConnectionFailed。这两个方法是事件处理器。clientConnectionFailed在反应器无法建立连接时被调用。clientConnectionLost在建立的连接被关闭或断开时调用。


告知反应器建立TCP连接,按照例子2-3的方法是调用reactor.connectTCP:


reactor.connectTCP('www.google.com',80,BasicClientFactory())


这一行告知反应器建立一个TCP连接到服务器www.google.com的80端口,通过BasicClientFactory来管理连接。







推荐阅读
  • 阿里云ecs怎么配置php环境,阿里云ecs配置选择 ... [详细]
  • 本文详细介绍了网络存储技术的基本概念、分类及应用场景。通过分析直连式存储(DAS)、网络附加存储(NAS)和存储区域网络(SAN)的特点,帮助读者理解不同存储方式的优势与局限性。 ... [详细]
  • 远程过程调用(RPC)是一种允许客户端通过网络请求服务器执行特定功能的技术。它简化了分布式系统的交互,使开发者可以像调用本地函数一样调用远程服务,并获得返回结果。本文将深入探讨RPC的工作原理、发展历程及其在现代技术中的应用。 ... [详细]
  • 优化联通光猫DNS服务器设置
    本文详细介绍了如何为联通光猫配置DNS服务器地址,以提高网络解析效率和访问体验。通过智能线路解析功能,域名解析可以根据访问者的IP来源和类型进行差异化处理,从而实现更优的网络性能。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 如何配置Unturned服务器及其消息设置
    本文详细介绍了Unturned服务器的配置方法和消息设置技巧,帮助用户了解并优化服务器管理。同时,提供了关于云服务资源操作记录、远程登录设置以及文件传输的相关补充信息。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 本文详细分析了Hive在启动过程中遇到的权限拒绝错误,并提供了多种解决方案,包括调整文件权限、用户组设置以及环境变量配置等。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • 微软Exchange服务器遭遇2022年版“千年虫”漏洞
    微软Exchange服务器在新年伊始遭遇了一个类似于‘千年虫’的日期处理漏洞,导致邮件传输受阻。该问题主要影响配置了FIP-FS恶意软件引擎的Exchange 2016和2019版本。 ... [详细]
  • CentOS 7.6环境下Prometheus与Grafana的集成部署指南
    本文旨在提供一套详细的步骤,指导读者如何在CentOS 7.6操作系统上成功安装和配置Prometheus 2.17.1及Grafana 6.7.2-1,实现高效的数据监控与可视化。 ... [详细]
  • 本文档汇总了Python编程的基础与高级面试题目,涵盖语言特性、数据结构、算法以及Web开发等多个方面,旨在帮助开发者全面掌握Python核心知识。 ... [详细]
  • Git管理工具SourceTree安装与使用指南
    本文详细介绍了Git管理工具SourceTree的安装、配置及团队协作方案,旨在帮助开发者更高效地进行版本控制和项目管理。 ... [详细]
author-avatar
Victoria625_176
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有