下面的代码不能在Windows正常工作(但确实在Linux上):看着插座将它们放在非阻塞模式
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(True)
sock.connect(address)
gobject.io_add_watch(
sock.fileno(),
gobject.IO_OUT | gobject.IO_ERR | gobject.IO_HUP,
callback)
片段的在各个地方的意见在巧舌如簧源,和其他地方提到,在Windows中,套接字在轮询期间处于非阻塞模式。因此回调self.outgoing_cb
的不断呼吁,并写入套接字失败,出现此错误消息:
[Errno 10035] A non-blocking socket operation could not be completed immediately
调用事先书面sock.setblocking(True)
来似乎并不回避这一点。通过降低投票的优先级,并忽略错误信息,它按预期工作,但远远抛出很多事件,并消耗大量的CPU。在Windows中有没有办法解决这个限制?
更新
我可能会指出,该轮询POLLOUT
的整点是,当你写叫你不会得到EAGAIN
/EWOULDBLOCK
。奇怪的错误消息,我得到的,我相信会是Windows平台上类似的2个错误代码。换句话说,我越来越gobject.IO_OUT
事件时,插座不会让我写成功,和把它变成阻塞模式仍然给我这个不恰当的错误。
另一个更新
在Linux上,在此工作正常,插座未切换到非阻塞模式,我收到IO_OUT
,当套接字将让我写不阻塞,或抛出错误。这是我想在Windows下最好地模拟/恢复的功能。
还注意到
从man poll
:
poll() performs a similar task to select(2): it waits for one of a set
of file descriptors to become ready to perform I/O.
POLLOUT
Writing now will not block.
从man select
:
A file descriptor is considered ready if it is possible to perform the corre‐
sponding I/O operation (e.g., read(2)) without blocking.
关于你从手册中引用的内容:它不会阻塞一定数量的字节,是正确的。但是......在成功运营的最后阶段,您仍然可以获得EAGAIN。它并没有告诉你这些字节是多少。因此,对这些事件之一的适当反应是成功读取或写入尽可能多的数据,然后在用尽该数字时获取EAGAIN(也称为EWOULDBLOCK)。 – asveikau 2009-11-21 00:55:27
@asveikau:EAGAIN仅适用于非阻塞套接字。如果select()返回阻塞套接字已准备好写入,它将立即接收尽可能多的字节并返回该数字。 – 2009-11-21 02:23:34
@Anacrolix我认为我们在这里讨论write()。如果你在阻塞套接字上选择(),并且它告诉你是时候写了,那么你的write()比可以立即发送的更多,它会被阻塞。此外,在阅读的案例中,既然你提到它......首先我不认为你写的是真的。但假设它是......你怎么知道可以读的上限?只需传入一个大缓冲区?这没有意义。最好在循环中读取(),而不要受到任意大小的限制。 – asveikau 2009-11-21 03:59:18