微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Windows上使用Glib观察套接字将使其处于非阻塞模式

以下代码在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)

在glib源文件中的各个地方的评论片断,以及其他地方都提到,在Windows中,在轮询期间套接字被置于非阻塞模式。 因此,不断调用self.outgoing_cb ,并写入到套接字失败,并显示以下错误消息:

[Errno 10035] A non-blocking socket operation Could not be completed immediately

在写作之前调用sock.setblocking(True)似乎并没有规避这一点。 通过降低轮询的优先级,并忽略错误信息,它可以正常工作,但是会对很多事件造成很大的影响,并消耗大量的cpu。 有没有办法解决这个限制在Windows中?

更新

在Windows上安装pango和GIO cabal时,Cullongtypes的构造函数不可见

为什么不设置DBUS_SESSION_BUS_ADDRESS时不支持g_file_copy操作

如何获得3g的调制解调器信号强度在C + +的Linux?

我可能会指出, POLLOUT的投票POLLOUT在于,当您进行写入调用时,您将不会收到EAGAIN / EWOULDBLOCK 。 我得到的奇怪的错误信息,我相信会是那些2错误代码的Windows等价物。 换句话说,我得到的gobject.IO_OUT事件时,套接字不会让我写成功,并将其置于阻塞模式仍然给我这个不恰当的错误

一个更新

在Linux上,这个工作正常,套接字不会切换到非阻塞模式,并且当套接字允许我写入没有阻塞或抛出错误时,我会收到IO_OUT 。 这是我想在Windows下最好的模拟/恢复function。

进一步说明

从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 (eg,read(2)) without blocking.

执行非阻塞I / O是否有问题? 如果使用阻塞I / O,使用轮询循环似乎有点奇怪。

当我编写这样的程序时,我倾向于执行以下操作:

缓冲我要发送到文件描述符的字节。

当所述缓冲区非空时只请求IO_OUT (或poll()当量, POLLOUT )事件。

当poll() (或等价的)已经表明你已经准备好写入时,发出写入。 如果你得到EAGAIN / EWOULDBLOCK ,从缓冲区中删除成功写入的字节,并等待下一次发送信号。 如果您成功编写了整个缓冲区,那么请停止向POLLOUT请求,以免虚假地唤醒。

(我的猜测是,Win32绑定正在使用WSAEventSelect和WaitForMultipleObjects()来模拟poll() ,但结果是一样的…)

我不知道你想要的阻塞套接字如何工作。 你一直在“醒来”,因为你在写作的时候要求把你叫醒。 你只想指定,当你有数据要写…但是,当它唤醒你时,系统不会真正告诉你有多少数据,你可以写没有阻塞,所以这是一个很好的理由,阻止I / O。

GIO自2.22起包含GSocket ,一个“低级网络套接字对象”。 然而,这还没有被移植到Windows上的pygobject 。

我不确定这是否有帮助(我不熟悉轮询功能或MFC套接字,不知道轮询是您的程序结构的要求),所以采取这一点盐:

但是为了避免写入时发生阻塞或EAGAIN,我们使用select,即将套接添加到传递给select的写集,如果select()返回rc = 0,则套接字将立即接受写操作。

我们在应用程序中使用的写循环是(以伪代码的形式):

set_nonblocking. count= 0. do { FDSET writefds; add skt to writefds. call select with writefds and a reaonsable timeout. if (select fails with timeout) { die with some error; } howmany= send(skt,buf+count,total-count). if (howmany>0) { count+= howmany. } } while (howmany>0 && count<total);

你可以使用Twisted ,它包括对GTK的支持 (甚至在Windows上),并且将处理Windows上非阻塞套接字想要引发的各种错误情况。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐