Я работаю над скрученным учебным руководством только для узнавания больше 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
Дело в том, что метод doRead
вызывается только , когда сокет «готов к чтению»: либо на нем есть какие-то данные, либо иначе все будет сделано (и тогда чтение вернет 0
). Таким образом, решение вашей проблемы не может быть в функции doRead
- все дело в коде , вызывающем только тогда, когда это необходимо.
Весь этот код находится в «реакторе» Twisted, к которому экземпляр PoetrySocket
добавляется в __ init __
(через метод реактора addReader
). Если вы хотите разобраться в механизмах twisted по-настоящему, без примесей, то, кстати, вы, кажется, попали в нужное место (за исключением, конечно, изучения самих исходников twisted ;-).