- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章使用Python的Twisted框架实现一个简单的服务器由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
。
预览 twisted是一个被设计的非常灵活框架以至于能够让你写出非常强大的服务器。这种灵活的代价是需要好通过好几个层次来实现你的服务器, 本文档描述的是Protocol层,你将在这个层次中执行协议的分析和处理,如果你正在执行一个应用程序,那么你应该在读过top level的为twisted写插件一节中的怎样开始写twisted应用程序之后阅读本章。这个文档只是和TCP,SSL和Unix套接字服务器有关,同时也将有另一份文档专门讲解UDP。 你的协议处理类通常是twisted.internet.protocol.Protocol的子类。许多协议处理继承于该类或者比该类更加方便的该类的子类。一个protocol类的实例可能反复连接,也可能在连接关闭之后销毁。这就意味着这些持续不断的配置信息不是保存在Protocol中。 这些持久性的配置被保存在工厂(Factory)类中,这些工厂类通常继承至twisted.internet.protocol.Factory,默认 的工厂类仅仅是实例化每个Protocol,然后设置他们的factory属性为这个默认的工厂实例本身。这就让每个Protocol都被存储,然后可能 修改,于是这样就形成了Protocol的持久性。 通常为多个端口或网络地址提供相同的服务是非常有用的。这就是为什么Factory不监听连接,并且实际上它不知道关于网络的任何事情。看 twisted.internet.interfaces.IReactorTCP.listenTCP,另一个IReactor*.listen*获得 更多的信息.
本文档将要讲解各个步骤.
Protocol 如上所述,这里将通过更多代码的辅助类和函数来了解它。一个twisted protocl通过异步方式处理数据。这就意味着protocol从不等待任何事件。相反的是在事件通过网络到达的时候作出响应.
1
2
3
4
|
from
twisted.internet.protocol
import
Protocol
class
Echo(Protocol):
def
dataReceived(
self
,data):
self
.transport.writed(data)
|
这是个非常简单的协议处理,仅仅是在获得数据的事件中简单的将接收到的数据发送回去,并没有对所有的事件进行响应。这里有一个Protocol响应其他事件的例子如下:
1
2
3
4
5
|
from
twisted.internet.protocol
import
Protocol
class
QOTD(Protocol):
def
connectionMade(
self
):
self
.transport.write(
"An apple a day keeps the doctor away/r/n"
)
self
.transport.loseConnection()
|
本Protocl在一个已知的引用刚开始连接上来的时候作出响应,发送了一条消息,然后终止了连接connectionMade事件通常是在由于连接对象建立初始连接时触发,就像上面的QOTD类实际上是RFC865号文档的一个协议基类connectionLost事件将在断开连接的时候触发。实例: 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<span style
=
"font-family: Monospaced; color: #0000a0;"
><strong>PythonCode: <
/
strong><
/
span><table style
=
"width: 100%; height: 20px;"
align
=
"center"
bgcolor
=
"#e3dfe3"
border
=
"1"
bordercolor
=
"#9da7ac"
cellpadding
=
"0"
cellspacing
=
"0"
>
<tbody><tr><td>
<div
class
=
"textBackGround"
style
=
"font-family:Courier New;font-size:9pt;"
><pre><span style
=
"color: blue;"
>
from
<
/
span> twisted.internet.protocol <span style
=
"color: blue;"
>
import
<
/
span> Protocol
<span style
=
"color: blue;"
>
class
<
/
span> Echo(Protocol):
<span style
=
"color: blue;"
>
def
<
/
span> connectionMade(
self
):
self
.factory.numProtocols
=
self
.factory.numProtocols
+
1
<span style
=
"color: blue;"
>
if
<
/
span>
self
.factory.numProtocols >
100
:
self
.transport.write(<span style
=
"color: #ff44a2;"
>
"Too many connections, <span style="
color: blue;
">try</span> later"
<
/
span>)
self
.transport.loseConnection()
<span style
=
"color: blue;"
>
def
<
/
span> connectionLost(
self
, reason):
self
.factory.numProtocols
=
self
.factory.numProtocols
-
1
<span style
=
"color: blue;"
>
def
<
/
span> dataReceived(
self
, data):
self
.transport.write(data)<
/
pre>
<
/
div>
<
/
td>
<
/
tr>
<
/
tbody>
<
/
table>
|
本实例中,connectionMade和connectionLost相互协作工作以保持factory内部的活动连接数量最多为100。每当有用户协议连接近来的时候,就先检测factory内部的活动连接数,如果数量超过100,就发送连接数太多等下试的消息,然后断开连接而connectionLost则在断开一个协议的时候触发,减去factory内部的协议数量.
Using the Protocol 。
在本节,我将要讲解怎样简单的去测试你的protocol。(想知道如何写出一个好的twisted的服务器,请看 <a href="http://fantix.org/twisted-doc-zh/nightly/online/howto/plugin.html">Writing Plug-Ins<br> for Twisted</a>),这里有一个代码将运行我们上面谈论的QOTD服务器: 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<!
-
-
.textBackGround {background
-
color:
#F0F5FD;}
-
-
>
<span style
=
"font-family: Monospaced; color: #0000a0;"
><strong>PythonCode: <
/
strong><
/
span><table style
=
"width: 100%; height: 20px;"
align
=
"center"
bgcolor
=
"#e3dfe3"
border
=
"1"
bordercolor
=
"#9da7ac"
cellpadding
=
"0"
cellspacing
=
"0"
>
<tbody><tr><td>
<div
class
=
"textBackGround"
style
=
"font-family:Courier New;font-size:9pt;"
><pre><span style
=
"color: blue;"
>
from
<
/
span> twisted.internet.protocol <span style
=
"color: blue;"
>
import
<
/
span> Protocol, Factory
<span style
=
"color: blue;"
>
from
<
/
span> twisted.internet <span style
=
"color: blue;"
>
import
<
/
span> reactor
<span style
=
"color: blue;"
>
class
<
/
span> QOTD(Protocol):
<span style
=
"color: blue;"
>
def
<
/
span> connectionMade(
self
):
self
.transport.write(<span style
=
"color: #ff44a2;"
>
"An apple a day keeps the doctor away/r/n"
<
/
span>)
self
.transport.loseConnection()
<span style
=
"color: green;"
>
# Next lines are magic:</span>
factory
=
Factory()
factory.protocol
=
QOTD
<span style
=
"color: green;"
>
# 8007 <span style="color: blue;">is</span> the port you want to run under. Choose something >1024</span>
reactor.listenTCP(
8007
, factory)
reactor.run()<
/
pre>
<
/
div>
<
/
td>
<
/
tr>
<
/
tbody>
<
/
table>
|
不必担心最后面的6条代码,稍后你将会在本文档中了解到他们。<br> 。
Helper Protocols 。
大部分protocols依赖于同类别的更低层次的超级类。最受欢迎的互联网协议是基于行,行通常是由CR_LF(回车换行组成) 然而,也有相当一部分协议是混合的,他们具有线性的基本节点,也有原始数据节点,比如HTTP/1.1。 在这样的情况下,我们可以使用LineReceiver,本协议类有两个不同的事件处理方法,lineReceived和rawDataReceived 默认情况下,只有lineReceived会被调用,每次读取一行,然而如果setRawMode被调用,protocol将调用rawDataReceived 来处理直到setLineMode被调用。下面有一个简单的例子说明如何使用lineReceiver
PythonCode: 。
1
2
3
4
5
6
7
8
|
from
twisted.protocols.basic
import
LineReceiver
class
Answer(LineReceiver):
answers
=
{
'How are you?'
:
'Fine'
,
None
:
"I don't know what you mean"
}
def
lineReceived(
self
, line):
if
self
.answers.has_key(line):
self
.sendLine(
self
.answers[line])
else
:
self
.sendLine(
self
.answers[
None
])
|
。
。
。
注意:界定符不是命令行的一部分 其他也有一些不流行的协议依然存在,比如netstring based 和 a prefixed-message-length 。
State Machines 。
许多twisted protocol handlers需要编写一个状态机来记录他们当前的状态,这里有几点编写状态机的建议: 1、不要编写大状态机,宁愿去实现一个抽象的状态机类 2、使用python的动态性质去创建没有限制的状态机,比如SMTP客户端 3、不要混合特定应用程序代码和协议处理代码,当协议处理器已经提出一个特别的具体要求,保持它作为一个方法调用.
Factories(工厂类) 。
如前面所说,通常twisted.internet.protocol.Factory不必子类化就可以开始工作。然而有时候protocol需要具体的 特殊的工厂配置信息或其他需求,在这样的情况下,就需要进行子类化了。 对于Factory来说,他只是简单的实例化特殊的 protocol协议类,实例化Factory,并且设置protocol属性:
。
PythonCode: 。
1
2
3
4
5
|
from
twisted.internet.protocol
import
Factory
from
twisted.protocols.wire
import
Echo
myFactory
=
Factory()
myFactory.protocol
=
Echo
|
。
。
。
如果需要简单的去构造一个有具体特殊信息的工厂类,那么一个factory函数是非常有用的
PythonCode
。
。
1
2
3
4
5
6
7
8
9
10
|
class
QOTD(Protocol):
def
connectionMade(
self
):
self
.transport.write(
self
.factory.quote
+
'/r/n'
)
self
.transport.loseConnection()
def
makeQOTDFactory(quote
=
None
):
factory
=
Factory()
factory.protocol
=
QOTD
factory.quote
=
quote
or
'An apple a day keeps the doctor away'
return
factory
|
。
。
。
。
一个Factory有两个方法以执行特定于应用程序的建立和拆除(由于一个Factory通常存在,所以常规下一般不在__init__或者 __del__中给他们分配与回收,有可能太早或太晚)。 下面是一个Factory的例子,本例将允许Protocol写一个日志文件: PythonCode
。
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
from
twisted.internet.protocol
import
Factory
from
twisted.protocols.basic
import
LineReceiver
class
LoggingProtocol(LineReceiver):
def
lineReceived(
self
, line):
self
.factory.fp.write(line
+
'/n'
)
class
LogfileFactory(Factory):
protocol
=
LoggingProtocol
def
__init__(
self
, fileName):
self
.
file
=
fileName
def
startFactory(
self
):
self
.fp
=
open
(
self
.
file
,
'a'
)
def
stopFactory(
self
):
self
.fp.close()
|
Putting it All Together(综合) 。
现在你已经了解了Factory并且想要执行QOTD作为一个可配置的quote服务器是吗?没有问题这里就有一个代码: PythonCode: 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
from
twisted.internet.protocol
import
Factory, Protocol
from
twisted.internet
import
reactor
class
QOTD(Protocol):
def
connectionMade(
self
):
self
.transport.write(
self
.factory.quote
+
'/r/n'
)
self
.transport.loseConnection()
class
QOTDFactory(Factory):
protocol
=
QOTD
def
__init__(
self
, quote
=
None
):
self
.quote
=
quote
or
'An apple a day keeps the doctor away'
reactor.listenTCP(
8007
, QOTDFactory(
"configurable quote"
))
reactor.run()
|
。
。
。
就是最后两句代码,还需要去理解。 listenTCP是一个将Factory连接到网络的方法,他使用了reactor的接口,让许多不同的循环处理网络代码,而不需要修改的 最终用户代码,就像这样。如前面所说,如果你想要写一个好的twisted服务器,而不是仅仅的20行,那么你需要使用 the Application object. 。
最后此篇关于使用Python的Twisted框架实现一个简单的服务器的文章就讲到这里了,如果你想了解更多关于使用Python的Twisted框架实现一个简单的服务器的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
谁能解释一下 Server.MapPath(".")、Server.MapPath("~")、Server.MapPath(@"之间的区别\") 和 Server.MapPath("/")? 最佳答案
我不知道,为什么我们要使用 Server.UrlEncode() & Server.UrlDecode()?!在 QueryString 中我们看到 URL 中的任何内容,那么为什么我们要对它们进行编
我已经通过 WHM 在我的一个域上安装了 ssl 证书。网站正在使用 https://xyz.com . 但是它不适用于 https://www.xyz.com .我已经检查了证书,它也适用于 www
我已经使用 WMI 检测操作系统上是否存在防病毒软件,itz 正常工作并通过使用命名空间向我显示防病毒信息,例如 win xp 和 window7 上的名称和实例 ID:\root\SecurityC
我们有 hive 0.10 版本,我们想知道是否应该使用 Hive Server 1 或 Hive Server2。另一个问题是连接到在端口 10000 上运行的 Hive 服务器,使用 3rd 方工
我想在 C++ 中使用 Windows Server API 设置一个 HTTPS 服务器,我使用了示例代码,它在 HTTP 上工作正常,但我就是不能让它在 HTTPS 上工作。 (我不想要客户端 S
我写了一个非常基本的类来发送电子邮件。我用 smtp 服务器对其进行了测试,它工作正常,但是当我尝试使用我公司的交换服务器时,它给出了这个异常: SMTP 服务器需要安全连接或客户端未通过身份验证。服
我的应用程序包含一个“网关”DataSnap REST 服务器,它是所有客户端的第一个访问点。根据客户端在请求中传递的用户名(基本身份验证),请求需要重定向到另一个 DataSnap 服务器。我的问题
我有一个 Tomcat 服务器和一个 Glassfish4 服务器。我的 Servlet 在 Tomcat 服务器上启动得很好,但在 Glassfish4 服务器上给我一个“HTTP Status 4
我在 vmware 上创建了一个 ubuntu 服务器。我用它作为文件服务器。如果我通过托管虚拟机的计算机进行连接,则可以访问它。我无法从同一网络上的其他计算机执行此操作。提前致谢! 最佳答案 首先确
如何重启 Rails 服务器?我从 开始 rails server -d 所以服务器是分离的 我知道的唯一方法就是去做ps 辅助 | grep rails 并 kill -9关于过程#但是像这样杀死进
我实际上正在尝试找到编写一个简单的 XMPP 服务器的最佳方法,或者找到一个占用空间非常小的服务器。我只关心XMPP的核心功能(状态、消息传递、群组消息传递)。目前还在学习 XMPP 协议(proto
我实际上正在尝试找到编写简单 XMPP 服务器的最佳方法,或者找到一个占用空间非常小的方法。我只关心 XMPP 的核心功能(统计、消息、组消息)。目前也在学习 XMPP 协议(protocol),所以
我们正在尝试从 Java JAX-RS 适配器访问 SOAP 1.1 Web 服务。 我们正在使用从 WSDL 生成的 SOAP 客户端。 但是当解码 SOAP 故障时,我们得到以下异常: ... C
目前,我和许多其他人正在多个平台(Windows、OS X 和可能的 Linux)上使用 Python HTTP 服务器。我们正在使用 Python HTTP 服务器来测试 JavaScript 游戏
我有一个连续运行的服务器程序(C#/.NET 2.0 on Linux with mono),我想从 PHP 脚本连接到它以在网站上显示状态信息。 目的是创建一个(某种)实时浏览器游戏(无 Flash
所以我有一个单页客户端应用程序。 正常流程: 应用程序 -> OAuth2 服务器 -> 应用程序 我们有自己的 OAuth2 服务器,因此人们可以登录应用程序并获取与用户实体关联的 access_t
我们刚刚将测试 Web 服务器从 Server 2008 升级到 Server 2012 R2。我们有一个部署我们网站的批处理脚本。当它将站点推送到服务器时,它现在失败了。奇怪的是,我可以使用相同的发
建议一些加载SpagoBI服务器的方法,我尝试了所有方法来解析spagobi服务器。在 Catalina 中,错误是 - * SEVERE: Unable to process Jar entry [
当我们点击应用程序服务器(apache tomcat)时,它会创建一个线程来处理我们的请求并与 tomcat 连接,建立连接,tomcat 创建另一个线程来处理请求并将其传递给连接,连接线程将其传递给
我是一名优秀的程序员,十分优秀!