在python协同例程中,两个连续的socket.recv()导致BlockingIOError

时间:2017-10-20 19:34:09

标签: python sockets nonblocking recv

我有一段python代码来练习python协同例程。 正如A. Jesse Jiryu Davis所述。

  • 首先,我定义了一个名为“ get ”的联合例程来获取某些内容 URL。
  • 然后我定义了一个任务类来迭代协同例程。
  • 然后我创建一个任务对象,打开一个网址。

如果我在协同例程中放入两个连续的socket.recv()方法,我收到错误消息: '第二个 chunk = s.recv(1000)行中无法立即完成非阻塞套接字操作

  • 但如果我将所有 yield 更改为time.sleep(1)并直接调用 get()在全局上下文中,两个连续的s.recv(1000)将会 没有错误。更连续的s.recv(1000)就可以了。

经过几天搜索和阅读python文档,我仍然不知道为什么会这样。我必须错过一些'python Gotchas',是吗?

我正在使用python 3.6进行测试。代码如下,我删除了所有不相关的代码,使下面的代码精确且与主题相关:

#! /usr/bin/python

import socket
import select
import time

selectors_read = []
selectors_write = []

class Task:
    def __init__(self, gen):
        self.gen = gen
        self.step()

    def step(self):
        try:
            next(self.gen)
        except StopIteration:
            return

def get():
    s = socket.socket()
    selectors_write.append(s.fileno())
    s.setblocking(False)
    try:
        s.connect(('www.baidu.com', 80))
    except:
        pass

    yield
    selectors_write.remove(s.fileno())

    print('[CO-ROUTINE] ', 'Send')
    selectors_read.append(s.fileno())
    s.send('GET /index.html HTTP/1.0\r\n\r\n'.encode())

    yield

    while True:
        chunk = s.recv(1000)
        chunk = s.recv(1000)
        if chunk:
            print('[CO-ROUTINE] received')
        else:
            selectors_read.remove(s.fileno())
            break
        # yield


task_temp = Task(get())

while True:
    for filenums in select.select(selectors_read, selectors_write, []):
        for fd in filenums:
            task_temp.step()

0 个答案:

没有答案