[英]Named pipe: ReadFile after ConnectNamedPipe return ERROR_BROKEN_PIPE
I reactivated code that I am sure used to work some months ago. 我重新激活了几个月前我确定曾经工作过的代码。 It drives me crazy but it does not anymore.
它让我发疯,但现在已经不复存在了。 I could not find an answer in other questions.
我在其他问题上找不到答案。
On the server side, I create a pipe using 在服务器端,我使用创建管道
#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));
Then a thread waits for incoming clients with ConnectNamedPipe
. 然后一个线程等待具有
ConnectNamedPipe
传入客户端。 ConnectNamedPipe
blocks until a client connects with 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
on the server then returns with TRUE
and GetLastError == 0
. 然后,服务器上的
ConnectNamedPipe
将返回TRUE
和GetLastError == 0
。 But when it tries to call ReadFile
to read incoming data on the pipe, ReadFile
immediately returns FALSE
and GetLastError==ERROR_BROKEN_PIPE
. 但是当它尝试调用
ReadFile
来读取管道上的传入数据时, ReadFile
立即返回FALSE
和GetLastError==ERROR_BROKEN_PIPE
。 On client side, CreateFile
has returned GetLastError==231
, "All pipe instances are busy". 在客户端,
CreateFile
返回GetLastError==231
,“所有管道实例都忙”。 Although it is the only client! 虽然它是唯一的客户! A call to
WaitNamedPipe(pipe, 2000)
returns with error code 121, "The semaphore timeout period has expired". 对
WaitNamedPipe(pipe, 2000)
调用返回错误代码121,“信号量超时期限已过期”。 Increasing the number of allowed clients in CreateNamedPipe
does not change anything. 增加
CreateNamedPipe
中允许的客户端数量不会改变任何内容。
It seems the pipe got completely broken in the moment the client tries to connect. 在客户端尝试连接的那一刻,管道似乎完全被破坏了。 But why?
但为什么? Both client and server run on the same machine with same user and even same session.
客户端和服务器在同一台机器上运行,具有相同的用户甚至同一会话。 Another call to
ConnectNamedPipe
then failed with GLE=232:"The pipe is being closed". 然后另一个对
ConnectNamedPipe
调用因GLE = 232而失败:“管道正在关闭”。
I also had other SECURITY_ATTRIBUTES
for CreateNamedPipe
, which shall allow for non-elevated users to connect, but that makes no difference. 我还有
CreateNamedPipe
其他SECURITY_ATTRIBUTES
,它允许非提升用户连接,但这没有区别。
Also I tried to use CallNamedPipe
on the client with the same result. 此外,我尝试在客户端上使用
CallNamedPipe
,结果相同。
PathFileExists is the pipe killer! PathFileExists是管道杀手! After hours of trying I finally found what breaks the pipe: a simple call to PathFileExists on the pipe name!
经过几个小时的尝试后,我终于找到了破坏管道的东西:在管道名称上简单调用PathFileExists! This was added recently on the client side to check whether the pipe is already created.
最近在客户端添加了此项以检查管道是否已创建。 I had a look at the code changes but I totally missed that.
我看了一下代码更改,但我完全错过了。 PathFileExists correctly returns true or false but seems to mess up the pipe (as I told it did not help to allow more than one client to connect).
PathFileExists正确返回true或false但似乎搞乱了管道(因为我告诉它不允许多个客户端连接)。 Argh!!!
哎呀!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.