命名管道:连接命名管道返回ERROR_BROKEN_PIPE后的读取文件
Named pipe: ReadFile after ConnectNamedPipe return ERROR_BROKEN_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
返回 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
,结果相同。
PathFileExists 是管道杀手!经过几个小时的尝试,我终于找到了破坏管道的原因:对管道名称上存在 PathFile 的简单调用!这是最近在客户端添加的,用于检查管道是否已创建。我看了一下代码更改,但我完全错过了。PathFileExists 正确返回 true 或 false,但似乎弄乱了管道(正如我所说,它无助于允许多个客户端连接)。唉!!
- 先进先出:一个进程永远不会从管道读取
- read() 在 select() 阻塞之后,当从生成的进程从管道读取时
- 读取文件挂在管道读取上
- 使用两个不同的管道C 读取和写入相同的过程
- 启动子进程时的争用条件导致从管道读取挂起
- 为什么从管道读取时libc++getline会阻塞,而libstdc++getline不会
- 如何从 GStreamer 管道读取数据中的特定字段
- 命名管道读取超时
- 使用“反引号”而不是管道读取值 |C++
- 从管道读取输入时出现scanf问题
- 从 Linux 中的多个非阻塞命名管道读取
- 父进程没有完全从命名管道读取数据
- 获取错误代码 998 尝试从命名管道读取时对内存位置的访问无效
- 无法从匿名管道读取
- 在dup2()之后使用std::cin从管道读取
- 为什么 ReadFile() 不返回 0 ?程序尝试永远从管道读取数据
- 执行控制台程序,写入标准输入并使用管道读取结果
- 从管道读取随机失败
- 为什么我的程序在管道读取过程中冻结?
- 为什么可以'd '从管道读取比我自己的程序使用ifstream更快