Вопрос по python, sockets – неблокирующая розетка, ошибка всегда

7
sock.setblocking(0)
try:
    data = sock.recv(1024)
 except socket.error, e:
    if e.args[0] == errno.EWOULDBLOCK: 
          print 'EWOULDBLOCK'
else:            
   if not data:   #recv over
      sock.close()
      print 'close================='       
   else:
      print 'recv ---data---------'
      poem += data

весь приведенный выше код находится в цикле.non-blocking socket(просто хочу проверить «неблокирующий сокет») для получения данных. Но всегда печатайте «EWOULDBLOCK», я не знаю почему?

Добавьте весь код, включая настройку сокета, версию Python и ОС, на которой вы работаете. StefanE
Для справки:os.strerror(e.args[0]) выведет вам строку с ошибкой. Alex

Ваш Ответ

2   ответа
3

Исключение вызвано дизайном, потому что вы используетеnon-blocking IO.

The major mechanical difference is that send, recv, connect and accept can return without having done anything. You have (of course) a number of choices. You can check return code and error codes and generally drive yourself crazy.

Цитируется изPython док

Если вы бежитеman errno 3увидите описаниеEWOULDBLOCK, Исключение является разумным, потому что еще нет данных для чтения.

10

Розетка неблокирующая, поэтомуrecv() вызовет исключение, если нет данных для чтения. Обратите внимание, что errno.EWOULDBLOCK = errno.EAGAIN = 11. Это способ, с помощью Python (на самом деле, ОС) сказать вам попробоватьrecv() снова позже.

Замечу, что вы закрываете сокет каждый раз, когда получаете это исключение. Это не поможет вообще. Ваш код должен быть примерно таким:

import socket, errno, time

sock = socket.socket()
sock.connect(('hostname', 1234))
sock.setblocking(0)

while True:
    try:
        data = sock.recv(1024)
        if not data:
            print "connection closed"
            sock.close()
            break
        else:
            print "Received %d bytes: '%s'" % (len(data), data)
    except socket.error, e:
        if e.args[0] == errno.EWOULDBLOCK: 
            print 'EWOULDBLOCK'
            time.sleep(1)           # short delay, no tight loops
        else:
            print e
            break

Для такого рода вещей,select Модуль, как правило, путь.

Лиsocket.timeout здесь исключение?
@zhenyuyang Я не понимаю, я скучаю, но сжатые циклы просто тратят циклы ЦП, когда он может делать что-то еще, например запускать другие потоки или процессы. Если вы продолжаете получать EWOULDBLOCK, нет данных для чтения. Если вы не хотите этого условия, почему вы используете неблокирующий режим?
Спасибо. Я нахожу проблему в том, что скучаюtime.sleep(1).о всем этим отпечаток "все" EWOULDBLOCK ".", почему "нет жестких петель"; является обязательным условием & # xFF1F; zhenyuyang
@CMCDragonkai: нет, исключение тайм-аута не произойдет, потому что сокет не является блокирующим. Если вы хотите тайм-ауты, используйтеsocket.settimeout() а затем обработать любойsocket.timeout исключения. Или, как правило, лучше использоватьselect()/poll() следить за розетками.
Есть лиsocket.timeout также соответствуют конкретнымerrno.?, если вы поймали это сsocket.error обработчик исключений?

Похожие вопросы