prosseek
prosseek

Reputation: 190809

Broadcasting and receiving data with Python

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?

Upvotes: 0

Views: 5873

Answers (2)

prosseek
prosseek

Reputation: 190809

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

Upvotes: 6

brice
brice

Reputation: 25039

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

Upvotes: 1

Related Questions