2010-07-18 72 views
1

我正在研究一个扭曲的教程,以了解更多的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

+0

我无法重现您的结果。当我将代码连接到服务器时,当服务器断开连接时,将打印“已完成”。你确定你连接的服务器实际上关闭了连接吗? 此外,你知道这个应用程序会更好地实现为协议,而不是IReadDescriptor,对吗? – 2010-07-18 15:44:44

回答

2

的一点是,方法doRead被调用only当套接字“准备好读取”时:或者它有一些数据,或者el这一切都完成了(然后,阅读将返回0)。因此,对于您的问题的解决方案不能在doRead函数中 - 只有在适当的时候,代码才会调用

该代码全部在Twisted“reactor”中,PoetrySocket的实例将其自身添加到__init__中(通过反应器的addReader方法)。如果你想了解真正的非合作深度的扭曲的机制,顺便说一句,你看起来是在正确的位置(当然是研究扭曲的来源自己的网络;-)。

+0

感谢您回复Alex。我并不是真的想解决任何问题,只是试图了解它是如何工作的。我仍然不确定在except块中的break语句之后会发生什么,因为它似乎根本没有达到“if not bytes:”块。 – 2010-07-18 04:13:46

+0

@Joseph,所以它从来没有被调用(在你的实验中)的套接字错误(这将返回有问题的条件),但只有当对方“挂断”(连接丢失)时才会被调用。 – 2010-07-18 04:46:17