2012-06-17 2 views
3

У меня есть передача UDP некоторых данных. Я могу открыть следующий клиент в python 2.6.1 под OSX 10.6.8, и он работает. Я могу поймать данные, все хорошо.Обмен широковещательным приемом UDP - пример python

Но: этот код «потребляет» порт, в котором я не могу открыть другой, вторая попытка связывания не удалась ... и я должен разрешить несколько слушателей. Вот код, который открывает порт:

import select, socket 
port = 58083  # port msg is broadcast upon 

# Create listening port 
# --------------------- 
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
try: 
    s.bind(('', port)) 
except: 
    print 'failure to bind' 
    s.close() 
    raise 
s.setblocking(0) 

... Поскольку UDP является предназначен для вещания к нескольким клиентам (среди прочего), я предполагаю, что я делаю что-то неправильно. Я просто не могу понять, что.

Я нашел пример на ActiveState, который предложил:

s.bind(('<broadcast>',port)) 

... но это просто не может каждый раз. Привязка к 0.0.0.0 работает, но также страдает от проблемы «одного клиента». Связывание с локальным IP (например, 192.168.1.100) не работает вообще. Удаление привязки не работает вообще.

Кто-нибудь?

+2

Определить, что «не работает». – EJP

+0

привязка к 192.168.1.100 возвращает «socket.error [Errno 48] Адрес уже используется» при запуске второго экземпляра. Удаление привязки с помощью 192.168.1.100 не приводит к отсутствию широковещательного приема. Удаление связывания с '' в качестве IP-адреса приводит к отсутствию приема. Добавление рекомендуемой строки не повредит клиенту 1, но клиент 2 сообщает об ошибке, как я описал ниже. Использование <broadcast> как строка получает меня Errno 49 Невозможно назначить запрошенный адрес – fyngyrz

ответ

2

Если вам нужно несколько процессов, чтобы слушать на 58083, вам необходимо установить SO_REUSEADDR на гнездо, прежде чем socket.bind()

import select, socket 
port = 58083  # port msg is broadcast upon 

# Create listening port 
# --------------------- 
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Allow other processes to 
                 # bind to port 
try: 
    s.bind(('0.0.0.0', port)) 
except: 
    print 'failure to bind' 
    s.close() 
    raise 
s.setblocking(0) 

После добавления бесконечного цикла в нижней части, и работает это дважды на моем Linux сервере (один раз как root, а другой как неприбыльный пользователь), я вижу:

[email protected]# lsof | grep 58083 
python 25908  root 3u  IPv4    284835  0t0  UDP *:58083 
python 25945 mpenning 3u  IPv4    284850  0t0  UDP *:58083 
[email protected]# 
+0

Не работает: 'socket.error: [Errno 48] Адрес уже используется – fyngyrz

+0

Можете ли вы запустить их как одного пользователя? – fyngyrz

+1

Да, я все еще не вижу проблем с тем же пользователем –

Смежные вопросы