2014-12-27 6 views
1

Ситуация

Я пишу клиент python, используя неблокирующие сокеты udp. Иногда я получаюДанных нет в наличии после выбора

[Errno 11] Ресурс временно недоступен

Насколько я знаю, это происходит потому, что я

  • Используйте неблокирующие сокеты
  • RECV() на сокете неблокируемом что не имеет данных

Мой код:

def doRequestReply(self, addr, msg, readTimeout=2, writeTimeout=2): 
    # Create Socket 
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    s.setblocking(0) 

    ... 
    # Send Request 
    ... 

    # Wait for Reply 
    readable, _, exceptional = select.select([s], [], [s], readTimeout) 
    if s in readable: 
     data = s.recv(1024) 

    ... 

    s.close() 

я иногда получаю:

Traceback (most recent call last): 
    File "/home/steffen/Desktop/shared/Monitor/CrawlerWorker.py", line 159, in run 
    if not self.DoPeerExchange(peer, log=True): 
    File "/home/steffen/Desktop/shared/Monitor/CrawlerWorker.py", line 106, in DoPeerExchange 
    msg_rep = self.doRequestReply(addr, msg_req) 
    File "/home/steffen/Desktop/shared/Monitor/CrawlerWorker.py", line 53, in doRequestReply 
    data = s.recv(1024) 
error: [Errno 11] Resource temporarily unavailable 

Вопрос

Как это возможно, что исключение может быть поднят. Я имею в виду, что выбор гарантирует, что данные готовы к чтению из этого сокета. Я не должен получать эту ошибку.

Я не могу найти какие-либо детали в документах. Я не хочу просто исключать ошибку, пока я не знаю, почему это происходит или что это значит. Кто-нибудь знает об этом поведении?

Спасибо,

Штеффен

Update 1

Серверная часть также использует UDP неблокирующие сокеты. Из этого сокета считывается только один поток, используя select перед получением данных.

# Create a TCP/IP socket 
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
server.setblocking(0) 

while running: 
    readable, _, exceptional = select.select([server], [], [server], 1) 
    if server in readable: 
     # Handle incoming connections 
     data, client_address = server.recvfrom(1024) 
     ... 

Примерно через час снова получил:

Traceback (most recent call last): 
    File "Sensor.py", line 87, in main 
    data, client_address = server.recvfrom(1024) 
error: [Errno 11] Resource temporarily unavailable 

ли выбрать на самом деле обеспечивает данные будут доступны? Что может быть причиной этого исключения?

+0

Есть ли несколько процессов, считываемых из одного и того же сокета? – Barmar

+0

Я думаю, что этого не может быть. Как вы видите, я создаю сокет в функции и закрываю его перед отъездом. Сокет не используется – Steffen

+1

Я видел это, но иногда код, который публикует здесь, сокращен от реальной вещи. – Barmar

ответ

-1

Try:

select.select([s], [], [], readTimeout) 

вместо

select.select([s], [], [s], readTimeout) 

Из документации:

выберите.выберите (Rlist, wlist, xlist [, таймаут])

  • Rlist: не ждать, пока готовы для чтения
  • wlist: ждать, пока готовы для записи
  • xlist: ждать «исключительного состояния» (см страница руководства для того, что система считает такое условие)

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

+0

Я не уверен, прав ли я. Если я удалю сокет из третьего списка, сокет все равно будет возвращен в моем читаемом списке. – Steffen

+0

Но я должен сначала проверить исключительный список вывода – Steffen

+1

«Исключительное условие» сложное, зависящее от платформы и в основном не относящееся к делу. –