扭曲的回调函数混乱
我正在编写一个扭曲的教程,只是为了了解更多 python,但似乎我在这里遇到了障碍。下面的 doRead() 函数是反应器的“回调”。我不明白的是 except 部分是如何工作的。
我阅读代码的方式是,如果 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())
棘手的部分是,如果它被阻止,那么 bytes 变量将不包含任何内容,并且会打印“完成”,但事实并非如此。或者至少它会打印类似“got 0 bytes”的内容,但它也没有。在我看来,当代码遇到来自 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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要点是,仅当套接字“准备好读取”时,
doRead
方法才会被调用:要么它上面有一些数据,要么全部完成(然后,读取将返回0
)。因此,您的问题的解决方案不能在doRead
函数中 - 一切都在仅在适当时调用它的代码中。该代码全部位于 Twisted“反应器”中,
PoetrySocket
实例将其自身添加到__init__
中(通过反应器的addReader
方法)。顺便说一句,如果您想真正深入地了解 Twisted 的机制,那么您似乎来对地方了(当然,不包括研究 Twisted 的来源本身;-)。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 return0
). So the solution to your problem cannot be in thedoRead
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'saddReader
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;-).