扭曲的self.transport.write在循环中工作

时间:2013-11-26 10:35:42

标签: python-2.7 twisted

我有以下代码,客户端每隔8秒就会向服务器发送一些数据,以下是我的代码

class EchoClient(LineReceiver):
    def connectionMade(self):
        makeByteList()
        self.transport.write(binascii.unhexlify("7777"))

        while 1:
            print "hello"
            lep = random.randint(0,4)
            print lep
            print binascii.unhexlify(sendHexBytes(lep))
            try:
                self.transport.write("Hello")
                self.transport.write(binascii.unhexlify(sendHexBytes(lep)))
            except Exception, ex1:
                print "Failed to send"
            time.sleep(8)

    def lineReceived(self, line):
        pass

    def dataReceived(self, data):
        print "receive:", data

while循环中的每个语句都执行除self.transport.write之外。服务器不接收任何数据。另外self.transport.write while while循环不执行。在这两种情况下都不会引发异常,但如果我删除while循环,则循环外的语句将正确执行。为什么会这样?请纠正我错误的地方?

1 个答案:

答案 0 :(得分:3)

扭曲的所有方法都是异步connectionMadelineReceived等所有方法都发生在同一个线程上。 Twisted反应器运行一个循环(称为事件循环),当这些事件发生时,它会调用诸如connectionMadelineReceived之类的方法。

connectionMade中有一个无限循环。一旦Python进入该循环,它就永远不会消失。建立连接后,您可以使用Twisted调用connectionMade,并且您的代码永远存在。 Twisted没有机会将数据实际写入传输或接收数据,它被卡在connectionMade

当您编写Twisted代码时,您必须了解的重点是您可能不会在Twisted线程上阻止。例如,假设我想在客户端连接后4秒发送“Hello”。我可以这样写:

class EchoClient(LineReceiver):
    def connectionMade(self):
        time.sleep(4)
        self.transport.write("Hello")

但这是错误的。如果2个客户端同时连接会发生什么?第一个客户端将进入connectionMade,我的程序将挂起4秒,直到发送“Hello”。

扭曲的方式是这样的:

class EchoClient(LineReceiver):
    def connectionMade(self):
        reactor.callLater(4, self.sendHello)

    def sendHello(self):
        self.transport.write("Hello")

现在,当Twisted进入connectionMade时,它会在未来4秒内调用reactor.callLater 计划一个事件。然后它退出connectionMade并继续完成它需要做的所有其他事情。在你掌握异步编程的概念之前,你无法继续使用Twisted。我建议你仔细阅读Twisted docs here

最后,一个不相关的说明:如果您有LineReceiver,则不应实施自己的dataReceived,否则会调用lineReceivedLineReceiver是一个协议,它实现了自己的dataReceived,它将数据缓冲并分解为行并调用lineReceived方法。