支持断开连接的仅发送协议的Twisted客户端

2 投票
1 回答
3205 浏览
提问于 2025-04-16 05:22

我决定尝试一下异步Python编程,使用的是twisted这个库。我已经实现了一些文档中的例子,但我很难找到一个我想写的非常简单的客户端的例子。

简单来说,我想要一个客户端,它可以和服务器建立一个TCP连接,然后从一个队列对象中发送以"\n"结尾的简单字符串消息到服务器。服务器不会回应任何消息,所以我的客户端是完全单向的。我觉得我需要的是这个例子和twisted.internet.protocols.basic.LineReceiver这个方便协议的某种组合。这听起来应该是twisted中最简单的事情之一,但我在网上看到的文档和例子似乎都不太合适。

1 个回答

1

我做的事情不是使用队列,而是展示一段代码,这段代码在连接建立后发送一行数据。这里有很多打印信息,可以帮助你理解发生了什么。

通常需要导入的一些东西:

from twisted.web import proxy
from twisted.internet import reactor
from twisted.internet import protocol
from twisted.internet.protocol import ReconnectingClientFactory 
from twisted.protocols import basic
from twisted.python import log
import sys
log.startLogging(sys.stdout)

你需要创建一个从行接收器派生的协议,并设置分隔符。在这个例子中,我在连接建立后简单地写入一个字符串“www”。关键是要查看twisted.internet.interface.py中的协议接口,了解协议的各种方法,它们的作用以及何时被调用。

class MyProtocol(basic.LineReceiver):

    #def makeConnection(self, transport):
    #    print transport       

    def connectionLost(self, reason):
        print reason
        self.sendData = False

    def connectionMade(self):
        print "connection made"
        self.delimiter = "\n"
        self.sendData = True
        print self.transport
        self.sendFromQueue()

    def sendFromQueue(self):
        while self.sendData:
            msg = dataQueue.get()
            self.sendLine(msg)
            # you need to handle empty queue
            # Have another function to resume 

最后,创建一个协议工厂,这样每当有连接时就会生成一个协议实例。查看方法:buildProtocol。

class myProtocolFactory():
    protocol = MyProtocol

    def doStart(self):
        pass

    def startedConnecting(self, connectorInstance):
        print connectorInstance

    def buildProtocol(self, address):
        print address
        return self.protocol()

    def clientConnectionLost(self, connection, reason):
        print reason
        print connection

    def clientConnectionFailed(self, connection, reason):
        print connection
        print reason

    def doStop(self):
        pass

现在你可以使用连接器来建立连接:

reactor.connectTCP('localhost', 50000, myProtocolFactory())
reactor.run()

我运行了这个程序,并将其连接到一个简单的服务器,这个服务器只会打印它接收到的内容,因此不会发送任何确认信息。以下是输出结果:

1286906080.08   82     INFO 140735087148064 __main__ conn_made: client_address=127.0.0.1:50277
1286906080.08   83    DEBUG 140735087148064 __main__ created handler; waiting for loop
1286906080.08   83    DEBUG 140735087148064 __main__ handle_read
1286906080.08   83    DEBUG 140735087148064 __main__ after recv
'www\n'

Recieved: 4

上面的例子并不具备容错能力。如果连接丢失,你可以通过从现有的twisted类 - ReconnectingClientFactory派生你的协议工厂来实现重新连接。Twisted几乎提供了你所需的所有工具 :)

class myProtocolFactory(ReconnectingClientFactory):
    protocol = MyProtocol

    def buildProtocol(self, address):
        print address
        return self.protocol()

供进一步参考

我建议你阅读: http://krondo.com/?page_id=1327

[编辑:根据下面的评论]

撰写回答