0

I'm making a packet generator and it's crucial to be able to send packets as steadily and as accurately as possible. The problem I'm having is that I send the packets using a while loop with time.sleep that is supposed to loop hundreds times/second, but since it takes additional and varying time to go through the loop it's hard to set a right sleeping time.

Here is the code I'm using:

while status == "1":
     try:
         s.send(message)
         data = s.recv(1500)
         status = self.clientstatus
         time.sleep(1.0 / (speed*100))
     except:
         status = "0"

EDIT:

Here is a working solution that I used

    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

using self with socket might cause some problems in the future though

1 Answer 1

3

One of the soundest ways to schedule periodic events, as close to regularly as a system that's of course not real-time will allow, is the sched module documented at https://docs.python.org/2/library/sched.html .

For your use case, I'd try:

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()

This will stay as close to one event every 1.0 / (speed*100) seconds as feasible -- if one event was delayed (we're not in a real hard time environment so the operating system can cause unpredictable delays) the next one will be scheduled nearer in the future, &c. The implied loop ends when nothing more is entered in sch.

Sign up to request clarification or add additional context in comments.

2 Comments

I'd like to test this but I have to create the socket outside the function oneround(). That means I'd need to pass socket, delay and message as arguments and then wouldn't be able to call the function again with sch.enterabs(). Is there a way around this (like making the arguments class wide) or should I make the server in oneround()?
Your suggestion worked perfectly after I got it right. Thank you alot. I'll add the working code here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.