我在 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()”时,self.transport.write("data") 函数会引发异常: 'NoneType' 对象没有属性 'write'。
我猜 self.transport 断开了。
我该如何解决?
最佳答案
我找到了解决方案。
当我们使用 UDP 时,当我们发送数据报时,如果在不到 1 秒后没有收到答复,“self.transport”将设置为 None 并调用“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()
关于python - 使用 Twisted (python) 为 UDP 套接字设置超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30891927/