gpt4 book ai didi

windows - 命名管道服务器,如何中断或超时等待客户端连接和传入数据

转载 作者:可可西里 更新时间:2023-11-01 14:43:38 34 4
gpt4 key购买 nike

我正在为 Windows 编写一个简单的命名管道服务器,调用 Windows API(在带有 JNA 的 Java 中,但这不相关)。

我想弄清楚如何避免服务器永远卡住,等待客户端连接或数据来自客户端。

服务器代码执行以下操作:

1) 它通过调用 CreateNamedPipe 创建管道,在 dwPipeMode 参数中使用 PIPE_WAIT

2) 它调用ConnectNamedPipe在客户端连接之前不会返回。

3) 它进入循环,通过调用ReadFile 重复从客户端读取消息。它在读取数据之前不会返回,并且对于每条接收到的消息,它都会通过调用 WriteFile 将消息发送回客户端作为响应。

4) 经过多次这样的对话,客户端和服务器将断开与管道的连接。

我只是希望能够在等待第 2 步的 ConnectNamedPipe 和第 3 步的 ReadFile 时设置超时,但我看不到在哪里设置超时。在 CreateNamedPipe 函数中有一个 nDefaultTimeOut 参数,但听起来并不是真正的目的; API 文档说:

默认超时值,以毫秒为单位,如果 WaitNamedPipe 函数指定 NMPWAIT_USE_DEFAULT_WAIT

因此 CreateNamedPipe 中的 nDefaultTimeOut arg 听起来像是将连接到管道的客户端用于其操作的默认超时,并且仅当他们调用 WaitNamedPipe 函数时。事实上,在我的测试中,0 或 1000 的值没有区别,对 ConnectNamedPipe 的调用永远不会返回(除非客户端连接)。我正在寻找的是服务器中的超时,而不是在调用 ConnectNamedPipeReadFile 时。

作为 CreateNamedPipe 的文档,对于带有 PIPE_WAITdwPipeMode 参数表示, 阻塞模式已启用。当在 ReadFile、WriteFile 或 ConnectNamedPipe 函数中指定管道句柄时,直到有数据要读取、所有数据都已写入或客户端已连接时,操作才会完成。使用此模式可能意味着在某些情况下无限期地等待客户端进程执行操作。

所以也许实现这种超时的方法是以非阻塞模式创建管道(使用 PIPE_NOWAIT 而不是 PIPE_WAIT)以便调用 ReadFile , WriteFileConnectNamedPipe 立即返回,然后以某种方式在循环中监视自己的事件(客户端连接或接收到数据),并在循环中检查自己是否超时或发生其他中断事件(如用户单击取消按钮)?

已添加:对于 ReadFile 调用,我似乎可以使用立即返回的 PeekNamedPipe 来检查是否有数据读取,然后才调用 ReadFile。我会试试的。但是对于 ConnectNamedPipe 的调用,我仍然遇到同样的问题。

已添加:正如我所怀疑和答案所证实的那样,作为管道的新手,我是从某种倾斜的角度来看待它们的,从这个角度来看,对超时的需求似乎比实际情况要大。

F.ex。想要超时调用 ReadFile 的原因是,如果我(服务器)在其中从客户端读取数据并且客户端突然关闭,有时我可能最终会卡在 中读取文件。但现在我知道,如果 ReadFile 正在从管道读取并且客户端关闭,ReadFile总是出错,所以执行不会卡在里面。

最佳答案

我建议您设置 FILE_FLAG_OVERLAPPED 并使用一个事件来检查/等待完成。

虽然这最初是为异步 IO 而设计的,但您可以改为将事件计时到您预定义的生存时间。

如果您随后想取消 I/O 操作,可以使用 CancelIo() 函数。如果您只是想做一些工作然后继续等待,您也可以这样做 - 等待超时不会自动取消 I/O,因此您不需要再次调用 ConnectNamedPipe。

您也可以,正如您自己建议的那样,设置 PIPE_NOWAIT 并轮询连接直到成功,在这个用例中,任何一种方式都应该带来相同的结果。但请注意,这是遗留功能,Microsoft 不鼓励使用此选项。

关于windows - 命名管道服务器,如何中断或超时等待客户端连接和传入数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35828965/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com