mod_fcgid windows 命名管道 2nd 和后续请求

Posted

技术标签:

【中文标题】mod_fcgid windows 命名管道 2nd 和后续请求【英文标题】:mod_fcgid windows named pipes 2nd and subsequent requests 【发布时间】:2017-01-11 15:17:58 【问题描述】:

所有,我正在为基于运行时的编程语言构建一个 fastCGI 接口,并在 Windows、Linux 和 UNIX 环境中运行。

我已经在该运行时内运行的程序代码中实现了 fastCGI 协议,但是我遇到了与 mod_fcgid 对话的 Windows 代码的问题。在这种情况下,我不能使用预构建的 dll 来公开 fastCGI 函数,但我可以从该运行时语言中调用大多数 C 函数。我无法修改运行时,因为它属于另一家公司......将其视为 php 或 perl 之类的语言。我正在尝试做的类似于创建一个类似于 dll 的代码集(它不是 dll)来处理 fastCGI 请求。虽然很多人会说我在这里“重新发明***”,但我别无选择使用某人的预构建 dll 来提供 fastCGI 的接口。

我已经成功实现了一切,我可以得到初始请求,并通过我的 fastCGI 界面返回一个网页。我遇到的问题是在 Windows 下运行时处理“下一个”请求。我的代码在 Linux 下运行时运行良好,我接受()套接字,读()写()进行处理,关闭()套接字,然后返回并再次接受(),我得到下一个请求和一切都完美无缺。

在 Windows 下 mod_fcgid 使用命名管道。在我的代码中,我使用 GetStdHandle() 来获取标准输入的句柄,然后使用 ReadFile() 和 WriteFile(),并且包装在 fastCGI 协议中的数据进入 mod_fcgid,然后在完成请求后进入浏览器,我使用 CloseHandle( ) 然后循环回到 GetStdHandle() 以等待下一个请求。

第一个请求一切正常,浏览器获取我的 cgi 输出。在 Linux 下使用套接字的相同代码会获得第二个和后续请求,并且工作起来就像一个魅力。

我的问题是:在 Windows 下运行时,处理第一个请求后,我无法让 mod_fcgid 向我发送第二个请求。它最终会杀死我的 Windows 进程并在其位置启动一个新进程。这当然不是我想要的。

在我发送 fastCGI EndRequest 和循环等待下一个请求进入之间,我一定是做错了什么。

为了从 mod_fcgid 获取初始请求,我使用 GetStdHandle(),然后使用 ReadFile() 和 WriteFile()(均来自 kernel32.dll),当我使用 EndRequest 完成协议时,我无法获取代码能够接收第二个请求的权利。

我试过 fflush() 我试过 FileFlushBuffers(),我试过不关闭 GetStdHandle() 给我的句柄,我根本无法从我的 Windows 应用程序中弄清楚 mod_fcgid 需要什么,所以我可以接收第二个和后续请求。

在第一次请求之后,关闭我的句柄,从 GetStdHandle 获取到 stdin 的句柄,然后坐在 ReadFile 上,ReadFile() 返回 0 字节,GetLastError() 总是返回 6(无效句柄)。

我根本无法弄清楚在第一个请求完成后用于清理的 C 函数以及在 Windows 下运行时能够等待下一个请求进入。正如我之前所说,当使用套接字而不是使用来自 STDIN 的句柄(即命名管道)的 Windows 时,代码在 Linux 下可以完美运行。

【问题讨论】:

你的意思是,它使用_un_named管道?这就是我在使用 STDIN/STDOUT 时所期望的。 我找不到任何文档来确认这一点,但根据 FastCGI 协议在 TCP/IP 上的工作方式,我希望您获得的句柄是 server 命名管道结束。 (我之前的评论,现在已删除,假设它是客户端;我的错误。)因此,您不想关闭句柄,而是先调用 DisconnectNamedPipe,然后调用 ConnectNamedPipe(它将阻塞,直到新请求准备好)。 哈利,谢谢。我确实相信我需要使用那些 NamedPipe 函数。我一直在研究 mod_fcgi 的源代码,其中包括人们可以用来包含在他们的应用程序中的 libfcgi.dll。我看到它使用 ConnectNamedPipe 和 DisconnectNamedPipe,它还使用了一些 IOCompletion,我不太了解它的用途,但我相信你对 NamedPipe 调用的权利。谢谢。 【参考方案1】:

Harry,您对使用 NamedPipe 函数的评论起到了作用,我需要在第一个请求结束时使用 FileFlushBuffers,然后使用 DisconnectNamedPipe,然后使用 ConnectNamedPipe 等待下一个请求进入。再次感谢您.

【讨论】:

以上是关于mod_fcgid windows 命名管道 2nd 和后续请求的主要内容,如果未能解决你的问题,请参考以下文章

windows命名管道

Windows 8 命名管道创建

Windows进程间通信—命名管道

Docker Windows 容器挂载命名管道

在 Windows 中枚举命名管道

为啥 os.path.exists() 会阻止 Windows 命名管道连接?