首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >双绞线self.transport.write内环工作

双绞线self.transport.write内环工作
EN

Stack Overflow用户
提问于 2013-11-26 10:35:42
回答 1查看 1.3K关注 0票数 1

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

代码语言:javascript
复制
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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-26 14:12:12

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

connectionMade中有一个无限循环。一旦Python进入了这个循环,它就永远也出不去了。当连接建立时,扭曲调用connectionMade,您的代码将永远停留在那里。扭曲没有机会将数据实际写入传输,或接收数据,它被卡在connectionMade中!

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

代码语言:javascript
复制
class EchoClient(LineReceiver):
    def connectionMade(self):
        time.sleep(4)
        self.transport.write("Hello")

但这样做是不对的。如果两个客户同时连接,会发生什么情况?第一个客户端将进入connectionMade,我的程序将挂起4秒,直到发送"Hello“为止。

扭曲的方式应该是这样的:

代码语言:javascript
复制
class EchoClient(LineReceiver):
    def connectionMade(self):
        reactor.callLater(4, self.sendHello)

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

现在,当Twisted进入connectionMade时,它将调用reactor.callLater来在未来的4秒内安排一个事件。然后它退出connectionMade,继续做它需要做的所有其他事情。除非您掌握异步编程的概念,否则不能继续使用Twisted。我建议你读一遍扭曲的医生们

最后,一个无关的注意事项:如果您有一个LineReceiver,您不应该实现您自己的dataReceived,它将使lineReceived不被调用。LineReceiver是一种实现自己的dataReceived的协议,它将数据缓冲和分解为行,并调用lineReceived方法。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20214625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档