Windows 上的 python select.select()

标签 python windows sockets select

我正在使用来自 here 的代码测试 UDP 穿孔.它适用于 Linux,但在 Windows 上报告错误。这是发生错误的代码片段:

while True:
    rfds, _, _ = select([0, sockfd], [], [])  # sockfd is a socket
    if 0 in rfds:
        data = sys.stdin.readline()
        if not data:
            break
        sockfd.sendto(data, target)
    elif sockfd in rfds:
        data, addr = sockfd.recvfrom(1024)
        sys.stdout.write(data)

错误信息:

Traceback (most recent call last):
  File "udp_punch_client.py", line 64, in <module>
    main()
  File "udp_punch_client.py", line 50, in main
    rfds, _, _ = select([0, sockfd], [], [])
select.error: (10038, '')

我知道这个错误与 Windows 上的 select 实现有关,每个人都引用了这个:

Note File objects on Windows are not acceptable, but sockets are. On Windows, the underlying select() function is provided by the WinSock library, and does not handle file descriptors that don’t originate from WinSock.

所以我有两个问题:

  1. [0, sockfd] 中的0 是什么意思?这是某种常用的技术吗?
  2. 如果 select 仅适用于 Windows 上的 socket,如何使代码与 Windows 兼容?

谢谢。

最佳答案

不幸的是,select 不会帮助您在一个线程中处理 stdin 和网络事件,因为 select 无法处理流 Windows 。您需要的是一种无阻塞地读取 stdin 的方法。您可以使用:

  1. stdin 的额外线程。这应该可以正常工作,并且是完成这项工作的最简单方法。如果您只需要等待 I/O 事件,则 Python 线程支持非常好。
  2. A greenlet类似于 gevent 中的机制补丁线程支持和标准库的大多数 I/O 函数,以防止它们阻塞 greenlets。还有像 twisted(见评论)这样的库提供非阻塞文件 I/O。这种方式是最一致的,但它应该要求使用与你的框架相匹配的风格来编写整个应用程序(twistedgevent,区别不大)。但是,我怀疑 twisted 包装器无法在 Windows 上从 stdin 进行异步输入(很确定他们可以在 *nix 上做到这一点,因为他们可能使用相同的 选择).
  3. 一些其他技巧。然而,大多数可能的技巧都相当丑陋。

关于Windows 上的 python select.select(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22251809/

相关文章:

python 简单的 wsgi 文件上传脚本 - 有什么问题?

c++ - windows下如何设置Qt程序的图标?

python - 似乎无法从 PyCharm 中的 GitHub 存储库中获取

apache - 在提供页面后,HTTP 套接字连接仍处于 TIME_WAIT 状态

sockets - 'ab' 程序在大量请求后卡住,为什么?

python - 使用 TCP 套接字发送/接收数据包

Python 请求模块 - POST 失败 - 无效字符 'o'

python - RDFLib 解析器无法识别 json-ld 格式

python - 当 python 脚本有未处理的异常时退出代码

ruby-on-rails - 我应该放弃在 Windows 下部署 Rails 吗?