繁体   English   中英

Windows命名管道问题

[英]Windows Named Pipe Problem

我正在编写一个通过命名管道与用户态应用程序通信的驱动程序。 userland应用程序通过调用CreateNamedPipe()创建命名管道,然后通过调用IOCTL将管道名称传递给驱动程序。 然后驱动程序通过调用ZwCreateFile()打开管道。

然后userland应用程序命中一个循环,该循环读取来自管道的请求,处理请求并将结果写回管道,即:

while(1) {
ReadFromPipe
ProcessRequest
WriteToPipe
}

驱动程序基本上将请求写入管道,然后直接读回答案:

WriteRequestToPipe
ReadAnswerFromPipe

我的问题是,如果在应用程序中发生WriteToPipe之前在驱动程序中发生ReadAnswerFromPipe,则ReadAnswerFromPipe永远不会返回。 所以基本上做

WriteRequestToPipe
Sleep(10 seconds)
ReadAnswerFromPipe

解决了这个问题。

我为什么看到这个?

澄清:我使用两个不同的单向管道,尽管应用程序最终成功调用WriteToPipe,但ReadAnswerFromPipe调用永远不会返回...

由于命名管道在任何给定时间都支持单向通信,因此您必须使用2个管道(如已建议的)进行真正的异步访问,或者同步访问单个管道(如步话机)。 信号量对象应该可以很好地工作。 如果只将CreateSemaphore()的Maximum Count参数设置为1,它将充当二进制信号量。 然后,您可以在客户端和服务器上的while(true)消息循环内的该信号量上使用ZwWaitForSingleObject() ,并且您将具有同步访问权限。

编辑:记得您正在编写驱动程序作为此服务器组件,因此您将需要特定于内核的函数和结构,驱动程序端的KSEMAPHORE结构。

管道通常被视为单向通信信道。

我相信最简单的解决方案是创建两个管道:一个用于应用程序→驱动程序消息,一个用于驱动程序→应用程序消息。

不知道你正在编写什么版本的Windows,或者你所处的开发环境,我不确定这一定会有所帮助,但它可能会有所帮助。

如果您确保每次从驱动程序发送请求时都从用户应用程序获得响应,则可以考虑使用API​​函数TransactNamedPipe()(有关完整使用文档,请参阅MSDN中的此页面 )。

它专门用于执行发送/接收,并将等到响应返回之前返回。

或者,你可以在'重叠'模式下使用这个功能,在这种情况下它会立即返回,之后你等待一个事件 - 你必须作为原始调用中'TransactionOverlapped'结构的一部分传入 - 知道你收到了答案。

最好使用IOCTL与userland进行通信。 你为什么需要管道?

ephemient是正确的。 您可以坚持使用单个管道,但是您必须在两端之间同步读取和写入。 添加的睡眠似乎对您有用,因为它允许在读取答案之前读取请求 - 但这很容易出错,因为一端的延迟可能导致错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM