【发布时间】:2009-12-15 15:48:13
【问题描述】:
我已经开始在 linux 和 windows 上使用 socketpairs,以便在两个平台上捕获子进程的输出。我通过将 STD* 复制到套接字对中的一个套接字上来做到这一点(我在 perl 中使用 Win32::SocketPair 用于 Windows 上的套接字对)。我这样做的主要原因是读取不会阻塞输出文件句柄。
我遇到的问题是 kill(0,...) 在 Windows 上不起作用,所以我需要另一种方法来检测进程是否关闭。我查看了 SO_KEEPALIVE,但这似乎不适用于套接字对...我使用了 setsockopt(...) 然后 getsockopt(...) 并且在调用 setsockopt() 之前和之后 SO_KEEPALIVE 选项关闭。
然后我开始研究轮询套接字上的事件。 POLLHUP 事件看起来很有希望,但我不确定当它们像这样使用时它是否有效。
我正在寻找自动化交互式程序(不,我不能使用除非它在 Windows 平台上不起作用......除非你找到一个可以做到的?)。我一直在 Windows 上使用“cat”进行测试(我安装了 cat.exe)。到目前为止看起来不错,但有两个问题:
- 无法检测进程是否死机(kill(0,...) 不起作用)
- 无法从子进程中检测到 EOF(sysread 似乎总是返回 undef 或读取的字节数,从不返回 0,即使在我关闭 ($sock, 1) 之后也是如此)
我可能在做一些非常愚蠢的事情,但我们将不胜感激任何建议/帮助。
更新:我开始使用 waitpid($pid, WNOHANG) 来检测“仍在运行”的情况,这很有帮助,因为在读取所有内容后进程似乎总是死亡。如果 pid 仍在运行,waitpid 返回 0。但是,它不是 EOF,总比没有好,但我仍在寻找其他输入。这显然并不理想。
UPDATE2:这个 Q/A 帮助解决了我的问题的 EOF 部分,并不完美,但更好: How epoll detect clientside close in Python?
【问题讨论】:
-
一般来说,套接字无法判断连接的另一端何时断开。这就是 TCP 的本质。出于这个原因,网络应用程序实现了心跳和关闭连接约定。
-
我想我认为这就是 KEEPALIVE 的用途,我弄错了吗?
-
KEEPALIVE 是告诉服务器尝试保持连接打开,但服务器可能不想或无法尊重它。通常使用 KEEPALIVE,有一个约定是在消息中包含消息长度(如 HTTP/1.1 中的“Content-length”标头),因此接收者确切知道要读取多少字节。
标签: windows perl sockets automation