flo*_*ark 6 python sockets windows udp
我有一些问题,我猜它是代码.
该应用程序用于"ping"某些自定义网络设备,以检查它们是否还活着.它使用特殊的UDP数据包每隔20秒对它们进行一次ping操作并期望响应.如果他们未能连续3次ping,则应用程序会向员工发送警告消息.
应用程序每周7天,每天24小时运行一次,每天随机播放一次(主要是2-5次),应用程序无法在10分钟的精确时间内收到UDP数据包,之后一切都恢复正常.在那10分钟内,只有1台设备似乎在回复,其他设备似乎已经死亡.我已经能够从日志中推断出来了.
我已经使用wireshark来嗅探数据包,并且我已经验证了ping数据包的输入和输入,所以网络部分似乎工作正常,一直到操作系统.计算机正在运行WinXPPro,有些没有配置防火墙.我在不同的计算机,不同的Windows安装和不同的网络上遇到此问题.
我真的不知道这里可能出现什么问题.
我附上了完成所有网络的代码的相关部分.这是在与应用程序其余部分分开的线程中运行的.
我提前感谢您提供的任何见解.
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)
Run Code Online (Sandbox Code Playgroud)
你没有提到它,所以我必须提醒你,既然你使用的是select()
那个套接字,最好是非阻塞的。否则你recvfrom()
可以阻止。如果处理得当,应该不会真正发生,但很难从简短的代码片段中看出。
然后您不必检查 UDP 套接字的可写性 - 它始终是可写的。
现在真正的问题是——你说数据包正在进入系统,但你的代码没有收到它们。这很可能是由于套接字接收缓冲区溢出造成的。过去 15 年中 ping 目标的数量是否有所增加?您正在为自己设置 ping 响应风暴,并且可能读取这些响应的速度不够快,因此它们会堆积在接收缓冲区中并最终被丢弃。
我的建议(按投资回报率排序):
SO_RCVBUF
一个很大的值。这将使您的网络堆栈能够更好地处理数据包突发。EWOULDBLOCK
。这将为您节省大量select()
电话。recvmmsg(2)
(如果存在)来使每个系统调用的多个数据包出列。希望这可以帮助。
归档时间: |
|
查看次数: |
820 次 |
最近记录: |