在twisted中调用connectTCP后调用sendLine()方法

0 投票
1 回答
657 浏览
提问于 2025-04-18 09:55

我做了一个简单的服务器,使用了LineReceiver。在用Telnet测试的时候,我可以顺利地发送和接收消息。

我想进一步发展一下,想用一个小的图形界面来发送和接收消息。

我想象中的做法是,创建一个连接函数,这个函数会调用reactor.run()方法,同时还会实例化一个ClientFactory类。我是根据我找到的这个例子来进行的:

#!/usr/bin/env python

# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.


from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
import sys

class EchoClient(LineReceiver):
    end="Bye-bye!"
    def connectionMade(self):
        self.sendLine("Hello, world!")
        self.sendLine("What a fine day it is.")
        self.sendLine(self.end)

    def lineReceived(self, line):
        print "receive:", line
        if line==self.end:
            self.transport.loseConnection()

    def sendMessage(self, line):
        self.sendLine(line)

class EchoClientFactory(ClientFactory):
    protocol = EchoClient

    def clientConnectionFailed(self, connector, reason):
        print 'connection failed:', reason.getErrorMessage()
        reactor.stop()

    def clientConnectionLost(self, connector, reason):
        print 'connection lost:', reason.getErrorMessage()
        reactor.stop()

def main():
    factory = EchoClientFactory()
    reactor.connectTCP('localhost', 1234, factory)
    reactor.run()

if __name__ == '__main__':
    main()

注意,当我调用main()函数时,connectionMade会发送那些消息。

我该如何同时运行reactor和工厂,并调用sendLine函数呢?

1 个回答

1

Twisted中的调用可以分为两种:一种是排队等待未来的操作,另一种是立即(或者说几乎立即)执行的操作,前提是反应器正在运行。你可以把这两种结合起来,安排一些事情在未来发生。(详细内容可以查看:安排未来的任务

比如,如果你想在未来的某个时刻调用sendLine,你可以使用reactor.callLater(5, sendLine, arg_to_sendLine)。这行代码会安排在调用callLater后5秒执行sendLine(前提是你的代码在reactor.run()状态下)。

你还提到:

我想象中的情况是,我会有一个连接函数来调用reactor.run()方法。

这句话让我有点担心,因为Twisted是一个全面的框架(在大多数Twisted程序中,reactor.run()和它的设置调用几乎就是整个main),它不仅仅是你想进行通信时才启动的东西(如果你只用它一部分,它的反应会很糟糕)。

撰写回答