Windows 命名管道无法正确响应并发请求

Posted

技术标签:

【中文标题】Windows 命名管道无法正确响应并发请求【英文标题】:Windows named pipe doesn't respond correctly for concurrent requests 【发布时间】:2013-06-08 02:34:37 【问题描述】:

我使用命名管道在一个程序内部进行内部通信(在 Windows XP 上)。当我连接 2-3 个客户端时,命名管道适用于多个连接。但是,当我同时应用多个连接(例如 10 个)时,它似乎被卡住了,ConnectNamedPipe() 只能接受少数连接,并且通信似乎被卡住了。

但是当我在客户端代码中调试时,我发现所有客户端 CreateFile 函数都正确返回了文件句柄(似乎是正确的句柄)。这很令人困惑,因为我观看了 CreateNamedPipe 循环,它只创建了大约一半的句柄......

服务器部分:

       while (!isPipeServerClosed)
        
            try
            
                filehandle = CreateNamedPipe(
                this.pipeName,
                DUPLEX | FILE_FLAG_OVERLAPPED,
                PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
                255,
                InBufferSize,
                InBufferSize,
                0,
                IntPtr.Zero);
                if (ConnectNamedPipe(filehandle, IntPtr.Zero) > 0)
                

                    PipeThread pipe = new PipeThread(filehandle);
                    sPipeThreadList.Add(pipe);
                
            
            catch (Exception exp)
            
                System.Console.WriteLine(exp.StackTrace);
            

        

客户端部分,简单的 Delphi 代码(即使我尝试使用 WaitNamedPipe 的行为也一样):

  FHandle := INVALID_HANDLE_VALUE;
  FHandle := CreateFile(PChar(FPipeName),GENERIC_READ or GENERIC_WRITE,
        0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
  // create the class
  if FHandle = INVALID_HANDLE_VALUE then
  begin
    Connected := false;
  end

我能知道我错过了什么吗?谢谢!

【问题讨论】:

不知道为什么投反对票。也许您可以提供有关循环失败的更多详细信息:发生了什么,是否有异常,返回的句柄无效等? GetLastError() 告诉你什么? 谢谢,正如@Chris 所说,管道没有正确创建。但是这些功能没有给我任何错误。我猜它们只是一些无证行为。 【参考方案1】:

您没有正确使用重叠操作。 In particular:

如果使用 FILE_FLAG_OVERLAPPED 打开 hNamedPipe,则 lpOverlapped 参数不能为 NULL。它必须指向一个有效的 OVERLAPPED 结构体。如果使用 FILE_FLAG_OVERLAPPED 打开 hNamedPipe 并且 lpOverlapped 为 NULL,函数可能错误地报告 连接操作完成。

另外,我想有时您的 ConnectNamedPipe 调用会返回错误,因为客户端尚未连接 (ERROR_IO_PENDING)。在这些情况下,当他们的连接完成时,您的客户将被“孤立”,因为您不会为他们创建 PipeThread

如果你想使用重叠模式,你应该做更多的研究并正确实施。或者,如果您从 CreateNamedPipe 的参数中删除 FILE_FLAG_OVERLAPPED,则 ConnectNamedPipe 将阻塞,直到客户端连接并且不会发生此问题,尽管您将遇到不同的问题:当您想要停止服务器时如何解除阻塞(您我会在 SO,IIRC 上找到一些答案)。

【讨论】:

以上是关于Windows 命名管道无法正确响应并发请求的主要内容,如果未能解决你的问题,请参考以下文章

Java中命名管道的并发读/写(在Windows上)

无法打开 Windows 命名管道进行写入?

windows命名管道

windows命名管道

无法在 Windows 7 中的命名管道内创建进程

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