扭曲的回调函数混乱

发布于 2024-09-10 05:08:05 字数 1815 浏览 4 评论 0原文

我正在编写一个扭曲的教程,只是为了了解更多 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦中的蝴蝶 2024-09-17 05:08:05

要点是,仅当套接字“准备好读取”时,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 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;-).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文