перепутанная функция обратного вызова - PullRequest
1 голос
/ 18 июля 2010

Я работаю над измененным учебником только для того, чтобы выучить больше Python, и кажется, что я наткнулся здесь на дорожный блок.Функция doRead () ниже является «обратным вызовом» реактора.То, что я не могу понять, как работает, кроме части.

Способ, которым я читаю код, состоит в том, что если бы bytes += self.sock.recv(1024) вызвал бы блок, то он достиг бы следующей части кода:

if e.args[0] == errno.EWOULDBLOCK:
    break

Тогда он продолжил бык следующему:

if not bytes:
    print 'Task %d finished' % self.task_num
    return main.CONNECTION_DONE
else:
    msg = 'Task %d: got %d bytes of poetry from %s'
    print  msg % (self.task_num, len(bytes), self.format_addr())

Хитрость для меня заключается в том, что если бы она блокировалась, тогда переменная байтов не содержала бы ничего и напечатала бы «конец», но это не так.Или, по крайней мере, он напечатал бы что-то вроде «получил 0 байтов», но это тоже не так.Мне кажется, что когда код встречает блок из вызова recv, он полностью пропускает вышеуказанную часть.Может кто-нибудь объяснить, почему это происходит?

Вывод выглядит примерно так:

Task 1: got 30 bytes of poetry from 127.0.0.1:10000
Task 3: got 10 bytes of poetry from 127.0.0.1:10002
Task 1: got 30 bytes of poetry from 127.0.0.1:10000
Task 3: got 10 bytes of poetry from 127.0.0.1:10002
Task 1: got 30 bytes of poetry from 127.0.0.1:10000
Task 3: got 3 bytes of poetry from 127.0.0.1:10002
Task 1: got 30 bytes of poetry from 127.0.0.1:10000

Это целая функция:

def doRead(self):
    bytes = ''

    while True:
        try:
            bytes += self.sock.recv(1024)
            if not bytes:
                break
        except socket.error, e: # I don't understand this part
            if e.args[0] == errno.EWOULDBLOCK:
                break
            return main.CONNECTION_LOST

    if not bytes:
        print 'Task %d finished' % self.task_num
        return main.CONNECTION_DONE
    else:
        msg = 'Task %d: got %d bytes of poetry from %s'
        print  msg % (self.task_num, len(bytes), self.format_addr())

    self.poem += bytes

Весь модуль вставлен сюда: http://pastebin.com/bUnXgbCA

1 Ответ

2 голосов
/ 18 июля 2010

Суть в том, что метод doRead вызывается только , когда сокет «готов к чтению»: либо на нем есть какие-то данные, либо все готово (а затем чтение вернется0).Таким образом, решение вашей проблемы не может быть в функции doRead - все это в коде , вызывающем , это только когда это уместно.

Этот код находится в скрученном «реакторе»,к которому экземпляр PoetrySocket добавляет себя в __init__ (с помощью метода addReader реактора).Если вы хотите понять закрученные механизмы в реальной глубине, между прочим, вы, кстати, оказались в нужном месте (конечно, за исключением изучения самих искаженных источников; -).

...