热门标签 | 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来管理连接。







推荐阅读
  • 本文深入探讨了网络编程中的基本概念,如指针、引用和可重入函数,并详细介绍了OSI七层模型和TCP/IP四层模型的功能与协议。同时,文章还对比了HTTP与HTTPS的区别,分析了HTTP请求报文的结构,讨论了TCP与UDP的主要差异,以及滑动窗口协议的工作原理。 ... [详细]
  • 深入理解IIS:全面解析与应用
    本文详细介绍了IIS(Internet Information Services)的功能及其在不同Windows系统中的应用,探讨了IIS如何支持多种网络服务,如Web、FTP、NNTP和SMTP,并解释了其在现代网站开发和服务器管理中的重要性。 ... [详细]
  • 本文详细介绍了如何在Ubuntu系统上快速安装和配置Bitnami版本的GitLab,包括下载安装文件、执行安装过程以及设置邮件服务等步骤。 ... [详细]
  • Python安全实践:Web安全与SQL注入防御
    本文旨在介绍Web安全的基础知识,特别是如何使用Python和相关工具来识别和防止SQL注入攻击。通过实际案例分析,帮助读者理解SQL注入的危害,并掌握有效的防御策略。 ... [详细]
  • Web网络基础
    目录儿1使用HTTP协议访问Web2HTTP的诞生2.1因特网的起源2.2互联网、因特网与万维网2.3万维网与HTTP3网络基础TCPIP3.1TCPIP协议族3.2TCPIP的分 ... [详细]
  • 优化联通光猫DNS服务器设置
    本文详细介绍了如何为联通光猫配置DNS服务器地址,以提高网络解析效率和访问体验。通过智能线路解析功能,域名解析可以根据访问者的IP来源和类型进行差异化处理,从而实现更优的网络性能。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 微软Exchange服务器遭遇2022年版“千年虫”漏洞
    微软Exchange服务器在新年伊始遭遇了一个类似于‘千年虫’的日期处理漏洞,导致邮件传输受阻。该问题主要影响配置了FIP-FS恶意软件引擎的Exchange 2016和2019版本。 ... [详细]
  • 本文探讨了 Spring Boot 应用程序在不同配置下支持的最大并发连接数,重点分析了内置服务器(如 Tomcat、Jetty 和 Undertow)的默认设置及其对性能的影响。 ... [详细]
  • Iptool 抓包工具使用指南:网络通信协议分析技巧
    本文旨在介绍如何利用 Iptool 抓包工具有效分析 Internet 通信协议,提供了一系列实用的操作技巧。对于希望深入了解网络通信细节的技术人员而言,这些信息将大有裨益。 ... [详细]
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社区 版权所有