Reputation: 43
I'm working on a twisted tutorial just to learn more python and it seems I've ran into a road block here. The doRead() function below is the "callback" of a reactor. What I can't understand is how the except part works.
The way I read the code is that if bytes += self.sock.recv(1024)
would've caused a block then it will reach the following part of the code:
if e.args[0] == errno.EWOULDBLOCK:
break
Then it would've continued to the following:
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())
The tricky part for me is that if it blocked, then bytes variable would've contained nothing and would've printed "finish" but it doesn't. Or at least it would've printed something like "got 0 bytes" but it also doesn't. It almost seems to me like when the code encounters a block from the recv call, it skips the above part completely. Can someone explain why this is happening?
Output is something like this:
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
This is the whole function:
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
The whole module is pasted here: http://pastebin.com/bUnXgbCA
Upvotes: 1
Views: 617
Reputation: 881567
The point is that method doRead
gets called only when the socket is "ready for reading": either it has some data on it, or else it's all done (and then, reading will return 0
). So the solution to your problem cannot be in the doRead
function -- it's all in the code calling it only when appropriate.
That code is all in the Twisted "reactor", to which the instance of PoetrySocket
adds itself in __init__
(via the reactor's addReader
method). If you want to understand twisted's mechanisms in real unalloyed depth, you seem to be at the right place, by the way (net of studying twisted's sources themselves, of course;-).
Upvotes: 2