如何在 python 中制作对数据包生成器足够可靠的 while 循环
How to make while loop in python that is reliable enough for packet generator
我正在制作数据包生成器,能够尽可能稳定和准确地发送数据包至关重要。我遇到的问题是我使用带有 time.sleep 的 while 循环发送数据包,它应该循环数百 times/second,但由于它需要额外和不同的时间来完成循环,所以很难设置正确的睡眠时间。
这是我使用的代码:
while status == "1":
try:
s.send(message)
data = s.recv(1500)
status = self.clientstatus
time.sleep(1.0 / (speed*100))
except:
status = "0"
编辑:
这是我使用的有效解决方案
def clientstart(self):
self.sch = sched.scheduler(time.time, time.sleep)
self.next_time = time.time()
self.sch.enterabs(self.next_time, 0, self.oneround, ())
self.reset.emit()
time.sleep(0.03)
n = 0
targetip = self.entry1.text()
host = targetip
port = 5001
speed = int(self.entry2.text())
self.delay = 1.0 / (speed*100)
if targetip:
self.s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
try:
self.s.connect((host,port))
except:
self.err1.emit(1)
n = n+1
openfile = open('1024')
self.message = openfile.read()
self.clientstatus = "1"
status = self.clientstatus
self.buttonswitch("2")
n = n+1
self.nn = 1
t = threading.Thread(target = self.temp)
t.setDaemon(True)
t.start()
self.err1.emit(2)
self.sch.run()
if n == 1:
self.err1.emit(4)
elif n == 4:
self.err1.emit(0)
self.s.close()
self.buttonswitch("3")
else:
self.err1.emit(3)
def oneround(self):
try:
self.s.send(self.message)
status = self.clientstatus
self.nn += 1
if status == '1':
self.next_time += self.delay
self.sch.enterabs(self.next_time, 0, self.oneround, ())
except:
pass
不过,将 self 与套接字一起使用可能会在将来引起一些问题
安排周期性事件的最合理方法之一是 https://docs.python.org/2/library/sched.html 中记录的 sched
模块,它尽可能接近定期发生的系统当然不是实时的。
对于您的用例,我会尝试:
import sched, time
sch = sched.scheduler(time.time, time.sleep)
delay = 1.0 / (speed*100)
next_time = time.time()
def oneround():
try:
s.send(message)
data = s.recv(1500)
status = self.clientstatus
if status == '1':
next_time += delay
sch.enterabs(next_time, 0, oneround, ())
except:
pass
sch.enterabs(next_time, 0, oneround, ())
sch.run()
这将尽可能接近每 1.0 / (speed*100)
秒一个事件——如果一个事件被延迟(我们不是在真正的困难时期环境中,因此操作系统可能会导致不可预测的延迟)下一个将在未来安排得更近,等等。当 sch
.
中不再输入任何内容时,隐含循环结束
我正在制作数据包生成器,能够尽可能稳定和准确地发送数据包至关重要。我遇到的问题是我使用带有 time.sleep 的 while 循环发送数据包,它应该循环数百 times/second,但由于它需要额外和不同的时间来完成循环,所以很难设置正确的睡眠时间。
这是我使用的代码:
while status == "1":
try:
s.send(message)
data = s.recv(1500)
status = self.clientstatus
time.sleep(1.0 / (speed*100))
except:
status = "0"
编辑:
这是我使用的有效解决方案
def clientstart(self):
self.sch = sched.scheduler(time.time, time.sleep)
self.next_time = time.time()
self.sch.enterabs(self.next_time, 0, self.oneround, ())
self.reset.emit()
time.sleep(0.03)
n = 0
targetip = self.entry1.text()
host = targetip
port = 5001
speed = int(self.entry2.text())
self.delay = 1.0 / (speed*100)
if targetip:
self.s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
try:
self.s.connect((host,port))
except:
self.err1.emit(1)
n = n+1
openfile = open('1024')
self.message = openfile.read()
self.clientstatus = "1"
status = self.clientstatus
self.buttonswitch("2")
n = n+1
self.nn = 1
t = threading.Thread(target = self.temp)
t.setDaemon(True)
t.start()
self.err1.emit(2)
self.sch.run()
if n == 1:
self.err1.emit(4)
elif n == 4:
self.err1.emit(0)
self.s.close()
self.buttonswitch("3")
else:
self.err1.emit(3)
def oneround(self):
try:
self.s.send(self.message)
status = self.clientstatus
self.nn += 1
if status == '1':
self.next_time += self.delay
self.sch.enterabs(self.next_time, 0, self.oneround, ())
except:
pass
不过,将 self 与套接字一起使用可能会在将来引起一些问题
安排周期性事件的最合理方法之一是 https://docs.python.org/2/library/sched.html 中记录的 sched
模块,它尽可能接近定期发生的系统当然不是实时的。
对于您的用例,我会尝试:
import sched, time
sch = sched.scheduler(time.time, time.sleep)
delay = 1.0 / (speed*100)
next_time = time.time()
def oneround():
try:
s.send(message)
data = s.recv(1500)
status = self.clientstatus
if status == '1':
next_time += delay
sch.enterabs(next_time, 0, oneround, ())
except:
pass
sch.enterabs(next_time, 0, oneround, ())
sch.run()
这将尽可能接近每 1.0 / (speed*100)
秒一个事件——如果一个事件被延迟(我们不是在真正的困难时期环境中,因此操作系统可能会导致不可预测的延迟)下一个将在未来安排得更近,等等。当 sch
.