Python overlapping timer with UDP listener
Question: I'm looking for insight on including a timer with/within the WHILE loop of a
UDP listener service. The service is part of a device auto-discovery system I
need to interact with.

The process requiring the listener has three requirements/responsibilities:

  * Broadcast a notification packet at initial socket bind (device is up)
  * Listen for and reply to "search" broadcasts
  * regardless of presence/absence of "search" broadcasts, broadcast a "still alive" packet every 30 minutes

Each of these tasks alone are no problem, and the first two are easy to
include. What I'm not comfortable with is "interrupting the listener" or
modifying the WHILE loop of the listener to send the "alive" packet.

If I "wait" for the interval, I suspend other processes. Will a Scheduler
object do the same, or allow us to continue? I can't multi-thread, because I
need to receive and send on a specific port, which is bound within the thread.

here is what I have...

    
    
    import time
    import socket
    import sys 
    import shutil
    import signal
    import string
    import re
    import os
    import socket
    import fcntl
    import struct
    
    HOST = ''
    PORT = 8888
    RESPONSE_MSG = 'Yes, I'm here'
    ALIVE_MSG = 'I'm alive'
    IDENTIFY_MSG = 'It's me'
    IP_ADDR = ''
    INTERVAL = 1800
    
    # Datagram (udp) socket
    try :
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        print 'Socket created'
    except socket.error, msg :
        print 'Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
        sys.exit() 
    
    try:
        s.bind((HOST, PORT))
    except socket.error , msg:
        print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
        sys.exit()
    
    # broadcast wake-up message
    s.sendto(IDENTIFY_MSG,'239.255.255.250')
    
    #now keep listening...how do I not stop listening while sending a packet on an interval?
    while 1:
        # receive data from client (data, addr)
        d = s.recvfrom(1024)
        data = d[0]
        source_addr = d[1]
    
        if not data: 
            break
    
        s.sendto(RESPONSE_MSG, source_addr)
    


Answer: I think I have what is a working solution. It "punts" on the looping
complexity a bit, but I believe it is a clean, maintainable, readable
solution.

I've created three specific .py scripts; one opens a socket to send the "wake-
up" packet, second opens a socket to send the "alive" packet, and a third that
opens up a socket to listen/respond to device search requests.

These are then imported into a "calling script" with a timer-based interrupt.

Here's how it looks...

    
    
    import udp_wakeup
    import udp_listen
    import udp_alive
    import shutil
    import string
    from threading import Timer
    import thread, time, sys
    from datetime import datetime as dt
    
    #dummy flag to ensure constant looping
    restart = 1
    
    def timeout():
        thread.interrupt_main()
    
    #Call and execute the wake-up packet broadcast
    udp_wakeup.main()
    
    #Initiate timer for 1800 seconds, or 30 minutes
    while restart = 1
      try:
        #Call and execute the listener routine
        Timer(1800, timeout).start()
        udp_listen.main()
      except:
        #On Timer expire, break from listener, call Alive-broadcast, reset timer and restart listener
        udp_alive.main()
    

