Python的UDP套接字半随机的接收失败(Python UDP socket semi-rando

2019-07-30 11:49发布

我有一些问题,我猜它的代码。

该应用程序是用来“平”一些定制的网络设备,以检查他们是否还活着。 它坪它们每20秒有一个特殊的UDP数据包,并预计响应。 如果他们不能回答连续3坪的应用程序发送警告信息给工作人员。

在应用程序运行24/7和次随机数天(2-5居多)的应用程序无法接收UDP数据包为10分钟的确切时间,在这之后一切都恢复了正常。 在这10分钟仅得1设备似乎正在回复,其他人似乎死了。 我已经能够从日志来推断。

我使用Wireshark的嗅探数据包,我验证过ping包会都出来,在,所以网络的一部分似乎是工作好了,一路操作系统。 计算机运行WinXPpro依照有的已经没有任何配置的防火墙。 我在不同计算机上的这个问题,不同的窗口和安装不同的网络。

我真的很茫然,什么可能是这里的问题。

我附加了该做的所有网络代码的相关部分。 这是从应用程序的其余部分一个单独的线程运行。

我感谢你提前为任何见解可能会提供。

def monitor(self):
    checkTimer = time()
    while self.running:
        read, write, error = select.select([self.commSocket],[self.commSocket],[],0)
        if self.commSocket in read:
            try:
                data, addr = self.commSocket.recvfrom(1024)
                self.processInput(data, addr)
            except:
                pass

        if time() - checkTimer > 20: # every 20 seconds
            checkTimer = time()
            if self.commSocket in write:
                for rtc in self.rtcList:
                    try:
                        addr = (rtc, 7) # port 7 is the echo port
                        self.commSocket.sendto('ping',addr)
                        if not self.rtcCheckins[rtc][0]: # if last check was a failure
                            self.rtcCheckins[rtc][1] += 1 # incr failure count
                        self.rtcCheckins[rtc][0] = False # setting last check to failure
                    except:
                        pass

        for rtc in self.rtcList:
            if self.rtcCheckins[rtc][1] > 2: # didn't answer for a whole minute
                self.rtcCheckins[rtc][1] = 0
                self.sendError(rtc)

Answer 1:

你不提它,所以我要提醒你,因为你正在使用select()套接字最好是非阻塞的。 否则,你的recvfrom()可以阻止。 当与适当的处理,但很难从短的代码片断告诉实在不应该发生的。

然后,你就不必检查UDP套接字可写性 - 它始终是可写的。

现在真正的问题 - 你是说包进入系统,但您的代码不接受他们。 这是最有可能是由于插座的溢出接收缓冲区。 难道平安目标的数量增加了那些过去的15年? 你是在和自己的一个ping响应风暴,恐怕不读那些响应速度不够快,所以他们堆放在接收缓冲器中,并最终会被丢弃。

我的投资回报率的顺序建议:

  • 摊开ping请求,不要为自己设定了一个DDOS。 查询,说,每次迭代一个系统,并保持最后检查时间每个目标。 这将允许你甚至出包出来,在数。
  • 增加SO_RCVBUF到一个较大的值。 这将使你的网络堆栈,以更好地与突发数据包处理。
  • 在一个循环中读取数据包,即一旦你的UDP套接字是可读的(假设它是非阻塞),读,直到你得到EWOULDBLOCK 。 这将节省您的一堆select()调用。
  • 看看你是否能沿的Linux的线路使用一些先进的Windows API recvmmsg(2)如果这样的事情存在,出列每个系统调用多个数据包。

希望这可以帮助。



Answer 2:

UDP不保证可靠传输。 现在,这可以工作,在接下来的一个小时,并在明年。 然后,在两年内将失败了整整一个小时的沟通。

分组的路由路径可能被堵塞在某些情况下。 当与TCP情况,发送人被告知的损失,并且发件人可能会尝试通过不同的途径路径发送。 因为UDP是“发送和忘记”传输协议,可能会丢失一些数据包的统计。

TL;博士使用TCP。



文章来源: Python UDP socket semi-randomly failing to receive