【问题标题】:Is it possible to set a timeout on a socket in Twisted?是否可以在 Twisted 中的套接字上设置超时?
【发布时间】:2010-09-18 07:35:07
【问题描述】:

我意识到我可能只是愚蠢并错过了一些重要的事情,但我无法弄清楚如何使用 reactor.listenUDP 在扭曲中指定超时。我的目标是能够指定一个超时,并且在所述时间之后,如果 DatagramProtocol.datagramReceived 没有被执行,让它执行一个回调或者我可以用来调用 reactor.stop() 的东西。任何帮助或建议表示赞赏。谢谢

【问题讨论】:

    标签: python networking sockets twisted


    【解决方案1】:

    一个更好的方法是使用twisted.protocols.policies.TimeoutMixin。它本质上是在做一个callLater,但抽象成一个Mixin

    【讨论】:

      【解决方案2】:

      我认为reactor.callLater 会比LoopingCall 工作得更好。像这样的:

      class Protocol(DatagramProtocol):
          def __init__(self, timeout):
              self.timeout = timeout
      
          def datagramReceived(self, datagram):
              self.timeout.cancel()
              # ...
      
      timeout = reactor.callLater(5, timedOut)
      reactor.listenUDP(Protocol(timeout))
      

      【讨论】:

        【解决方案3】:

        对于 reactor,我们必须使用 callLater。 connectionMade 时开始超时倒计时。 收到线路时重置超时倒计时。

        这里是

        # -*- coding: utf-8 -*-
        
        from twisted.internet.protocol import Factory
        from twisted.protocols.basic import LineReceiver
        from twisted.internet import reactor, defer
        
        _timeout = 27
        
        
        class ServiceProtocol(LineReceiver):
        
            def __init__(self, users):
                self.users = users
        
        
            def connectionLost(self, reason):
                if self.users.has_key(self.name):
                    del self.users[self.name]
        
            def timeOut(self):
                if self.users.has_key(self.name):
                    del self.users[self.name]
                self.sendLine("\nOUT: 9 - Disconnected, reason: %s" % 'Connection Timed out')
                print "%s - Client disconnected: %s. Reason: %s" % (datetime.now(), self.client_ip, 'Connection Timed out' )
                self.transport.loseConnection()
        
            def connectionMade(self):
                self.timeout = reactor.callLater(_timeout, self.timeOut)
        
                self.sendLine("\nOUT: 7 - Welcome to CAED")
        
            def lineReceived(self, line):
                # a simple timeout procrastination
                self.timeout.reset(_timeout)
        
        class ServFactory(Factory):
        
            def __init__(self):
                self.users = {} # maps user names to Chat instances
        
            def buildProtocol(self, addr):
                return ServiceProtocol(self.users)
        
        port = 8123
        reactor.listenTCP(port, ServFactory())
        print "Started service at port %d\n" % port
        reactor.run()
        

        【讨论】:

          【解决方案4】:

          由于 Twisted 是事件驱动的,因此您本身不需要超时。您只需在收到数据报时设置一个状态变量(如 datagramRecieved)并注册一个检查状态变量的looping call,在适当的情况下停止反应器然后清除状态变量:

          from twisted.internet import task
          from twisted.internet import reactor
          
          datagramRecieved = False
          timeout = 1.0 # One second
          
          # UDP code here
          
          def testTimeout():
              global datagramRecieved
              if not datagramRecieved:
                  reactor.stop()
              datagramRecieved = False
          
          
          l = task.LoopingCall(testTimeout)
          l.start(timeout) # call every second
          
          # l.stop() will stop the looping calls
          reactor.run()
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-12-20
            • 2018-06-21
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多