Broadcasting and receiving data with Python

2019-09-06 17:28发布

问题:

I'm trying to broadcast some data and received it using python. This is the code that I came up with.

from socket import *
import threading

class PingerThread (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run (self):
        print 'start thread'
        cs = socket(AF_INET, SOCK_DGRAM)
        cs.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        cs.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
        cs.sendto('This is a test', ('192.168.65.255', 4499))

a = PingerThread() 
a.start()

cs = socket(AF_INET, SOCK_DGRAM)
data = cs.recvfrom(1024) # <-- waiting forever

However, the code seems to wait forever at cs.recvfrom(1024). What might be wrong?

回答1:

Your thread may send its data before you start listening.

Add a loop in your thread to stop the problem

from socket import *
import threading
import time

class PingerThread (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run (self):
        for i in range(10):
          print 'start thread'
          cs = socket(AF_INET, SOCK_DGRAM)
          cs.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
          cs.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
          cs.sendto('This is a test', ('192.168.1.3', 4499))
          time.sleep(1)

a = PingerThread() 
a.start()


cs = socket(AF_INET, SOCK_DGRAM)
try:
    cs.bind(('192.168.1.3', 4499))
except:
    print 'failed to bind'
    cs.close()
    raise
    cs.blocking(0)
data = cs.recvfrom(1024) # <-- waiting forever
print data


回答2:

There are three issues in the code.

  1. the listener is not binding to anything.
  2. opened socket is not closed.
  3. Sometimes, the thread spawns so quickly that the listener just misses the broadcast data.

This is the modified and working code.

from socket import *
import time
import threading

port = 4490
class PingerThread (threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run (self):
        print 'start thread'
        cs = socket(AF_INET, SOCK_DGRAM)
        cs.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        cs.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)

        time.sleep(0.1) # issue 3 solved
        cs.sendto('This is a test', ('192.168.65.255', port))

a = PingerThread()
a.start()

cs = socket(AF_INET, SOCK_DGRAM)
try:
    cs.bind(('192.168.65.255', port)) # issue 1 solved
except:
    print 'failed to bind'
    cs.close()
    raise
    cs.blocking(0)

data = cs.recvfrom(20)  
print data
cs.close() # issue 2 solved