【发布时间】:2016-07-02 10:35:50
【问题描述】:
我重新激活了几个月前可以使用的代码。它让我发疯,但它不再。我在其他问题中找不到答案。
在服务器端,我使用
创建了一个管道#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,结果相同。
【问题讨论】:
-
请提供Minimal, Complete, and Verifiable example,说明您是如何在两端使用管道的。
-
我猜你有一些流氓程序连接到你的管道然后关闭。您可以尝试更改管道的名称,看看是否有任何变化。如果失败,我建议使用Process Monitor 查找原因。
-
如果@rodrigo 的猜测是正确的(而且看起来不错),那么在 ConnectNamedPipe() 成功后立即在服务器中尝试 GetNamedPipeClientProcessId() 也是值得的。
-
我更改了管道名称但没有成功,GetNamedPipeClientProcessId() 返回正确的客户端 pid。我将创建一个完整的示例(抱歉,我过于关注 Minmal... :()
标签: c++ windows winapi server named-pipes