【发布时间】:2015-06-17 12:41:46
【问题描述】:
我在 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”对象没有“写”属性。
我猜 self.transport 已断开连接。
我该如何解决这个问题?
【问题讨论】:
-
"这是个好主意吗?" -- 这取决于您的特定用例,不是吗?
-
我只想生成一个超时。就像套接字库一样,当我们使用“socket.settimeout(5)”在我们执行“socket.recvfrom(1024)”时引发超时错误
-
超时的目的是什么?如果我们在 x 时间内没有收到确认,我们会提出超时并中止?这不是 TCP 吗?
-
就我而言,TCP 是绝对不可能的。超时的目的正如您所解释的那样。如果我在发送数据 5 秒后没有收到 ACK,我需要引发超时以通知我的应用程序数据包丢失。
-
您可能还需要更智能地处理
timeoutCallId。例如,两次取消单个调用是错误的 - 如果您收到两个数据报,这就是当前发生的情况。