写这个主要是为了自己理解Twisted的文档
建立一个finger服务
你不需要调用Twisted,Twisted会自己运行。reactor是Twisted的主循环,想python的其他主循环一样。每个Twisted只有一个reactor。一旦启动他就会不停的运行下去,响应一个又一个请求。
from twisted.internet import reactor返回当前的reactor。如果你不选择一个reactor的话,它会默认选择。
1 from twisted.internet import protocol, reactor, endpoints 2 3 class FingerProtocol(protocol.Protocol): 4 pass 5 6 class FingerFactory(protocol.ServerFactory): 7 protocol = FingerProtocol 8 9 fingerEndpoint = endpoints.serverFromString(reactor, \"tcp:1079\") 10 fingerEndpoint.listen(FingerFactory()) 11 reactor.run()
这个流程看过前两章的应该很熟悉了,先创建协议,再创建工厂,然后主循环。
1 from twisted.internet import protocol, reactor, endpoints 2 3 class FingerProtocol(protocol.Protocol): 4 def connectionMade(self): 5 self.transport.loseConnection() 6 7 class FingerFactory(protocol.ServerFactory): 8 protocol = FingerProtocol 9 10 fingerEndpoint = endpoints.serverFromString(reactor, \"tcp:1079\") 11 fingerEndpoint.listen(FingerFactory()) 12 reactor.run()
这个是增加了一个连接之后的初始化配置
1 from twisted.internet import protocol, reactor, endpoints 2 from twisted.protocols import basic 3 4 class FingerProtocol(basic.LineReceiver): 5 def lineReceived(self, user): 6 self.transport.loseConnection() 7 8 class FingerFactory(protocol.ServerFactory): 9 protocol = FingerProtocol 10 11 fingerEndpoint = endpoints.serverFromString(reactor, \"tcp:1079\") 12 fingerEndpoint.listen(FingerFactory()) 13 reactor.run()
这个是按行读取数据,就是按照你的\\r\\n读取数据,之后关闭连接
写一个读取用户名,返回错误,断开连接的finger
1 from twisted.internet import protocol, reactor, endpoints 2 from twisted.protocols import basic 3 4 class FingerProtocol(basic.LineReceiver): 5 def lineReceived(self, user): 6 self.transport.write(b\"No such user\\r\\n\") 7 self.transport.loseConnection() 8 9 class FingerFactory(protocol.ServerFactory): 10 protocol = FingerProtocol 11 12 fingerEndpoint = endpoints.serverFromString(reactor, \"tcp:1079\") 13 fingerEndpoint.listen(FingerFactory()) 14 reactor.run()
这个就是按行读取,返回一句话,之后关闭连接
1 from twisted.internet import protocol, reactor, endpoints 2 from twisted.protocols import basic 3 4 class FingerProtocol(basic.LineReceiver): 5 def lineReceived(self, user): 6 self.transport.write(self.factory.getUser(user)+ b\"\\r\\n\") 7 self.transport.loseConnection() 8 9 class FingerFactory(protocol.ServerFactory): 10 protocol = FingerProtocol 11 12 def getUser(self, user): 13 return b\"No such user\" 14 15 fingerEndpoint = endpoints.serverFromString(reactor, \"tcp:1079\") 16 fingerEndpoint.listen(FingerFactory()) 17 reactor.run()
增加获取用户名的函数
在协议之中调用工厂方法,可以用self.factory,这个就是指向工厂的,因为工厂类实际上是它的父类。
1 from twisted.internet import protocol, reactor, endpoints 2 from twisted.protocols import basic 3 4 class FingerProtocol(basic.LineReceiver): 5 def lineReceived(self, user): 6 self.transport.write(self.factory.getUser(user) + b\"\\r\\n\") 7 self.transport.loseConnection() 8 9 class FingerFactory(protocol.ServerFactory): 10 protocol = FingerProtocol 11 12 def __init__(self, users): 13 self.users = users 14 15 def getUser(self, user): 16 return self.users.get(user, b\"No such user\") 17 18 fingerEndpoint = endpoints.serverFromString(reactor, \"tcp:1079\") 19 fingerEndpoint.listen(FingerFactory({ b\'moshez\' : b\'Happy and well\'})) 20 reactor.run()
初始化一个字典,如果你输入的用户名没有在字典里边,就会返回默认值。
Defereds
1 from twisted.internet import protocol, reactor, defer, endpoints 2 from twisted.protocols import basic 3 4 class FingerProtocol(basic.LineReceiver): 5 def lineReceived(self, user): 6 d = self.factory.getUser(user) 7 8 def (err): 9 return \'Internal error in server\' 10 d.addErrback( ) 11 12 def writeResponse(message): 13 self.transport.write(message + b\'\\r\\n\') 14 self.transport.loseConnection() 15 d.addCallback(writeResponse) 16 17 class FingerFactory(protocol.ServerFactory): 18 protocol = FingerProtocol 19 20 def __init__(self, users): 21 self.users = users 22 23 def getUser(self, user): 24 return defer.succeed(self.users.get(user, b\"No such user\")) 25 26 fingerEndpoint = endpoints.serverFromString(reactor, \"tcp:1079\") 27 fingerEndpoint.listen(FingerFactory({b\'moshez\': b\'Happy and well\'})) 28 reactor.run()
在这个里边,我么使用了defer,其实也就仅仅修改了getUser方法。Defereds循序由事件驱动程序,也就是说,如果程序中的一个任务正在等待数据,程序可以去执行其他操作,这叫做异步执行。
上边的代码测试了一下,是按照队列执行的,就是说两个客户端发送数据,如果第一个客户端设置延迟返回5秒,那么之后5秒后,第二个客户端才会被响应。
解释一下deferred:
大家可以去看
https://www.cnblogs.com/zhangjing0502/archive/2012/05/16/2504415.html 作者:很多不懂呀。。
Twisted
1 from twisted.application import service, strports 2 from twisted.internet import protocol, reactor, defer 3 from twisted.protocols import basic 4 5 class FingerProtocol(basic.LineReceiver): 6 def lineReceived(self, user): 7 d = self.factory.getUser(user) 8 9 def (err): 10 return \'Internal error in server\' 11 d.addErrback( ) 12 13 def writeResponse(message): 14 self.transport.write(message + b\'\\r\\n\') 15 self.transport.loseConnection() 16 d.addCallback(writeResponse) 17 18 class FingerFactory(protocol.ServerFactory): 19 protocol = FingerProtocol 20 21 def __init__(self, users): 22 self.users = users 23 24 def getUser(self, user): 25 return defer.succeed(self.users.get(user, b\"No such user\")) 26 27 application = service.Application(\'finger\', uid=1, gid=1) 28 factory = FingerFactory({b\'moshez\': b\'Happy and well\'}) 29 strports.service(\"tcp:79\", factory, reactor=reactor).setServiceParent( 30 service.IServiceCollection(application))
可能你已经发现了,我们的协议类从上边开始就没变过,事实上,以后也很少会变了,主要是在工厂里更改。
这个例子是告诉twisted您的应用程序在哪里,使用的是application
from twisted.application import service,strports
在这里我们没有再使用serverFormString来设置地址端口,我们用了他的应用程序来启动,strports.service。注意,当它被实例化的时候,这个程序对象不会引用协议和工厂!
任何把application当做父对象的服务将会在twisted启动的时候被启动。总之,他就是来管理启动服务和关闭服务的。
继续阅读与本文标签相同的文章
手把手教 Vue-环境搭建
学习Python语言,这些酷毙的工具你知道几个?
-
5G开启万物互联新畅想
2026-05-19栏目: 教程
-
5 分钟开发一个 AI 检测人体框架的 App
2026-05-19栏目: 教程
-
API网关
2026-05-19栏目: 教程
-
8.29直播预告 | 阿里云InfluxDB数据采集演示
2026-05-19栏目: 教程
-
通过阿里云活动购买了云服务器,再怎么购买和挂载数据盘
2026-05-19栏目: 教程
