我重新激活了几个月前我确定曾经工作过的代码。它让我发疯,但现在已经不复存在了。我在其他问题上找不到答案。
在服务器端,我使用
创建管道#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
将返回TRUE
和GetLastError == 0
。但是当它试图调用ReadFile
来读取管道上的传入数据时,ReadFile
会立即返回FALSE
和GetLastError==ERROR_BROKEN_PIPE
。
在客户端,CreateFile
已返回GetLastError==231
,“所有管道实例都忙”。虽然它是唯一的客户!对WaitNamedPipe(pipe, 2000)
的调用将返回错误代码121,“信号量超时期限已过期”。
增加CreateNamedPipe
中允许的客户端数量不会改变任何内容。
在客户端尝试连接的那一刻,管道似乎完全被破坏了。但为什么?客户端和服务器在同一台机器上运行,具有相同的用户甚至同一会话。
然后对ConnectNamedPipe
的另一次调用因GLE = 232而失败:“管道正在关闭”。
我还为SECURITY_ATTRIBUTES
提供了其他CreateNamedPipe
,这将允许非提升用户进行连接,但这没有任何区别。
此外,我尝试在客户端上使用CallNamedPipe
,结果相同。
答案 0 :(得分:3)
PathFileExists是管道杀手!经过几个小时的尝试后,我终于找到了破坏管道的东西:在管道名称上简单调用PathFileExists!最近在客户端添加了此项以检查管道是否已创建。我看了一下代码更改,但我完全错过了。 PathFileExists正确返回true或false但似乎搞乱了管道(因为我告诉它不允许多个客户端连接)。哎呀!