使用Twisted(python)为UDP套接字设置超时

2024-09-30 12:21:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我在python程序中使用Twisted。我每分钟发送数据,在UDP套接字上接收数据,我需要设置一个超时。在

我找到了一个办法,但我想知道这是不是一个好办法。在

我的代码是这样的:

class UDPSocket(DatagramProtocol):
   def startProtocol(self):
       self.transport.connect(self.HOST, self.PORT)
       reactor.callLater(1, self.send_data)

   def send_data(self):
       reactor.callLater(60, self.send_data)
       self.transport.write("Some data")
       self.timeoutCallId = reactor.callLater(5, raise_timeout)

   def datagramReceived(self, data, (host, port)):
       if self.timeoutCallId.active():
           self.timeoutCallId.cancel()
       #Do something with data

   def raise_timeout(self):
       #Do something to manage timeout

reactor.listenUDP(port, UDPSocket())
reactor.run()

谢谢你的建议

编辑:

它有效,但我有个问题。在

如果发生超时,我将正确地进入raise_timeout函数,但是当下一个“send_data()”被调用时自传输写入(“data”)函数引发异常: “NoneType”对象没有属性“write”。在

我想是吧自行运输已断开连接。在

我该怎么解决呢?在


Tags: selfsenddataportdeftimeoutdowrite
1条回答
网友
1楼 · 发布于 2024-09-30 12:21:26

我找到了解决办法。在

当我们使用UDP时,当我们发送数据报时,如果在不到1秒后没有收到应答,”自行运输“”设置为“无”,并调用“stopProtocol”方法。一旦我们离开“stopProtocol”方法,reactor将停止侦听指定的UDP端口。在

这是我的解决方案代码:

class UDPSocket(DatagramProtocol):
    def __init__(self, mainreactor):
        self._reactor = mainreactor

    def startListenUDP(self):
        try :
            self._reactor.listenUDP(KeepAlive.PORT, self)
        except Exception, e :
            pass

    def startProtocol(self) :
        self.transport.connect(self.host, self.port)

    def stopProtocol(self):
        print "Transport disconnected !"
        self._reactor.callLater(0.1, self.startListenUDP)

    def raise_timeout(self) :
        print "Timeout !"

    def datagramReceived(self, datagram, host):
        try :
            if self.timeout_id.active():
                self.timeout_id.cancel()
        except Exception, e :
            pass
        print datagram

    def sendDatagram(self):
        datagram = "Some Data"
        try :
            self.transport.write(datagram)
            self.timeout_id = self._reactor.callLater(TIMEOUT, 
                self.raise_timeout)
        except Exception, e :
            self._reactor.callLater(0.1, self.startListenUDP)

def main():
    protocol = UDPSocket(reactor)
    t = reactor.listenUDP(PORT, protocol)
    l = task.LoopingCall(protocol.sendDatagram)
    l.start(60)
    reactor.run()

#MAIN
if __name__ == '__main__':
    main()

相关问题 更多 >

    热门问题