命名pipe道:ConnectNamedPipe后的ReadFile返回ERROR_BROKEN_PIPE

我重新激活了几个月前曾经工作过的代码。 这让我发疯,但现在不行了。 其他问题我找不到答案。

服务器端,我使用创build一个pipe道

#define MAX_MESSAGE_LENGTH 1024 SECURITY_ATTRIBUTES sa; SECURITY_DESCRIPTOR sd; InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, TRUE, static_cast<PACL>(0), FALSE); sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = &sd; sa.bInheritHandle = FALSE; auto pipe_name = _T("\\\\.\\pipe\\") + _serviceName; HANDLE pipe = CreateNamedPipe( pipe_name.c_str(), PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, MAX_MESSAGE_LENGTH, MAX_MESSAGE_LENGTH, // buffer lengths (advisory) 0, // default timeout of 50ms when WaitNamedPipe uses NMPWAIT_USE_DEFAULT_WAIT &sa)); 

然后一个线程用ConnectNamedPipe等待传入的客户端。 ConnectNamedPipe块,直到客户端连接

 HANDLE pipe = CreateFile( pipe_name.c_str(), // pipe name GENERIC_READ | // read and write access GENERIC_WRITE, 0, // no sharing NULL, // default security attributes OPEN_EXISTING, // opens existing pipe FILE_ATTRIBUTE_NORMAL, // default attributes NULL); // no template file 

服务器上的ConnectNamedPipe然后返回TRUEGetLastError == 0 。 但是当它试图调用ReadFile来读取pipe道上的传入数据时, ReadFile立即返回FALSEGetLastError==ERROR_BROKEN_PIPE 。 在客户端, CreateFile已经返回GetLastError==231 ,“所有pipe道实例都很忙”。 虽然它是唯一的客户! 对WaitNamedPipe(pipe, 2000)调用将返回错误代码121,“信号量超时期限已过期”。 增加CreateNamedPipe中允许的客户端数量不会改变任何内容。

看起来pipe道在客户端尝试连接的时候完全被破坏了。 但为什么? 客户端和服务器都在相同的用户甚至同一个会话的同一台机器上运行。 对ConnectNamedPipe另一个调用失败,GLE = 232:“pipe道正在closures”。

我也有其他SECURITY_ATTRIBUTESCreateNamedPipe ,这将允许非高架用户连接,但没有任何区别。

此外,我试图在客户端使用CallNamedPipe具有相同的结果。

PathFileExists是管道杀手! 经过几个小时的努力,我终于找到了什么破坏管道:简单的调用管道名称上的PathFileExists! 这是最近在客户端添加来检查管道是否已经创建。 我看了一下代码的变化,但是我完全错过了。 PathFileExists正确返回true或false,但似乎弄乱了管道(因为我告诉它不允许多个客户端连接)。 哎呀!