我正在使用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.
所以我有两个问题:
[0, sockfd]
中0
是什么意思?这是一种常用的技巧吗?select
只在Windows上与socket
一起工作,如何使代码窗口兼容?谢谢你。
正如答案所建议的,我创建了另一个线程来处理输入流,它工作正常。 这是修改后的代码:
不幸的是,
select
无法帮助您在一个线程中处理stdin
和网络事件,因为select
无法在Windows上处理流。您需要的是一种无阻塞地读取stdin
的方法。您可以使用:stdin
的额外线程。这应该工作得很好,是做这项工作最简单的方法。如果您只需要等待I/O事件,那么Python线程支持就可以了。twisted
(请参阅注释)的库提供非阻塞文件I/O。这种方式是最一致的,但它应该要求使用与框架匹配的样式来编写整个应用程序(twisted
或gevent
,差异不显著)。但是,我怀疑twisted
包装器不能从Windows上的stdin
异步输入(非常肯定它们可以在*nix上执行,因为它们可能使用相同的select
)。相关问题 更多 >
编程相关推荐