使用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从不等待任何事件。相反的是在事件通过网络到达的时候作出响应。
from twisted.internet.protocol import Protocol class Echo(Protocol): def dataReceived(self,data): self.transport.writed(data)
这是个非常简单的协议处理,仅仅是在获得数据的事件中简单的将接收到的数据发送回去,并没有对所有的事件进行响应。这里有一个Protocol响应其他事件的例子如下:
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事件将在断开连接的时候触发。实例:
<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 class="brush:php;toolbar:false"><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)
本实例中,connectionMade和connectionLost相互协作工作以保持factory内部的活动连接数量最多为100。每当有用户协议连接近来的时候,就先检测factory内部的活动连接数,如果数量超过100,就发送连接数太多等下试的消息,然后断开连接而connectionLost则在断开一个协议的时候触发,减去factory内部的协议数量。
Using the Protocol
在本节,我将要讲解怎样简单的去测试你的protocol。(想知道如何写出一个好的twisted的服务器,请看 Writing Plug-Ins
for Twisted),这里有一个代码将运行我们上面谈论的QOTD服务器:
<!-- .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 class="brush:php;toolbar:false"><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()
不必担心最后面的6条代码,稍后你将会在本文档中了解到他们。
Helper Protocols
大部分protocols依赖于同类别的更低层次的超级类。最受欢迎的互联网协议是基于行,行通常是由CR_LF(回车换行组成)
然而,也有相当一部分协议是混合的,他们具有线性的基本节点,也有原始数据节点,比如HTTP/1.1。
在这样的情况下,我们可以使用LineReceiver,本协议类有两个不同的事件处理方法,lineReceived和rawDataReceived
默认情况下,只有lineReceived会被调用,每次读取一行,然而如果setRawMode被调用,protocol将调用rawDataReceived
来处理直到setLineMode被调用。下面有一个简单的例子说明如何使用lineReceiver:
PythonCode:
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:
from twisted.internet.protocol import Factory from twisted.protocols.wire import Echo myFactory = Factory() myFactory.protocol = Echo
如果需要简单的去构造一个有具体特殊信息的工厂类,那么一个factory函数是非常有用的:
PythonCode:
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:
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:
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.

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











DeepSeek Xiaomi를 다운로드하는 방법? Xiaomi App Store에서 "Deepseek"을 검색하십시오. 요구 사항 (검색 파일, 데이터 분석)을 식별하고 DeepSeek 기능이 포함 된 해당 도구 (예 : 파일 관리자, 데이터 분석 소프트웨어)를 찾으십시오.

DeepSeek을 효과적으로 사용하는 열쇠는 질문을 명확하게 요청하는 것입니다. 질문을 직접 그리고 구체적으로 표현하십시오. 구체적인 세부 사항 및 배경 정보를 제공합니다. 복잡한 문의의 경우 여러 각도 및 반박 의견이 포함됩니다. 코드의 성능 병목 현상과 같은 특정 측면에 중점을 둡니다. 당신이 얻는 답변에 대한 비판적 사고를 유지하고 당신의 전문 지식을 바탕으로 판단하십시오.

강력한 시맨틱 분석 알고리즘과 함께 제공되는 검색 기능을 사용하면 검색 의도를 정확하게 이해하고 관련 정보를 제공 할 수 있습니다. 그러나 인기가없는 최신 정보 또는 고려해야 할 문제가있는 검색의 경우 키워드를 조정하거나보다 구체적인 설명을 사용하고 다른 실시간 정보 소스와 결합하며 DeepSeek이 필요한 도구라는 것을 이해해야합니다. 적극적이고 명확하며 세련된 검색 전략.

DeepSeek은 프로그래밍 언어가 아니라 깊은 검색 개념입니다. DeepSeek을 구현하려면 기존 언어를 기반으로 선택해야합니다. 다양한 응용 프로그램 시나리오의 경우 적절한 언어 및 알고리즘을 선택하고 기계 학습 기술을 결합해야합니다. 코드 품질, 유지 관리 및 테스트가 중요합니다. 귀하의 요구에 따라 올바른 프로그래밍 언어, 알고리즘 및 도구를 선택하고 고품질 코드를 작성하면 성공적으로 구현할 수 있습니다.

질문 : DeepSeek은 회계에 이용 가능합니까? 답변 : 아니요, 재무 데이터를 분석하는 데 사용할 수있는 데이터 마이닝 및 분석 도구이지만 회계 소프트웨어의 회계 기록 및 보고서 생성 기능이 없습니다. DeepSeek을 사용하여 재무 데이터를 분석하려면 데이터 구조, 알고리즘 및 DeepSeek API에 대한 지식으로 데이터를 처리하기 위해 코드를 작성해야합니다. 잠재적 문제 (예 : 프로그래밍 지식, 학습 곡선, 데이터 품질).

Python은 배우기 쉽고 강력한 기능을 통해 초보자에게 이상적인 프로그래밍 입문 언어입니다. 기본 사항은 다음과 같습니다. 변수: 데이터(숫자, 문자열, 목록 등)를 저장하는 데 사용됩니다. 데이터 유형: 변수의 데이터 유형(정수, 부동 소수점 등)을 정의합니다. 연산자: 수학 연산 및 비교에 사용됩니다. 제어 흐름: 코드 실행(조건문, 루프) 흐름을 제어합니다.

Python은 초보자에게 문제 해결 능력을 부여합니다. 사용자 친화적인 구문, 광범위한 라이브러리 및 변수, 조건문 및 루프 사용 효율적인 코드 개발과 같은 기능을 제공합니다. 데이터 관리에서 프로그램 흐름 제어 및 반복 작업 수행에 이르기까지 Python은 제공합니다.

DeepSeekapi Access and Call에 대한 자세한 설명 : 빠른 시작 안내서이 기사는 DeepSeekapi에 액세스하고 전화하는 방법에 대해 자세히 안내하여 강력한 AI 모델을 쉽게 사용할 수 있도록 도와줍니다. 1 단계 : API 키를 가져와 DeepSeek 공식 웹 사이트에 액세스하고 오른쪽 상단의 "오픈 플랫폼"을 클릭하십시오. 특정 수의 무료 토큰을 얻게됩니다 (API 사용량을 측정하는 데 사용됨). 왼쪽의 메뉴에서 "Apikeys"를 클릭 한 다음 "Apikey 만들기"를 클릭하십시오. Apikey (예 : "테스트")의 이름을 지정하고 생성 된 키를 즉시 복사하십시오. 한 번만 표시 되므로이 키를 올바르게 저장하십시오.
