我正试着用一个命名的管道来写,并把同样的东西读回来。考虑下面的代码片段(为了简洁起见,错误处理被剥离了):
const char * pipeName = "\\\\.\\pipe\\pipe";
const char * buffWrite = "SOME TEXT";
unsigned buffLength = strlen(buffWrite);
char buffRead[1024];
DWORD nWritten, nRead;
HANDLE hPipe = CreateNamedPipe(pipeName,
PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, 0);
HANDLE hFile = CreateFile(pipeName, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
WriteFile(hFile, buffWrite, buffLength, &nWritten, 0);
CloseHandle(hFile);
//the next line fails with >>All pipe instances are busy.<<
hFile = CreateFile(pipeName, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
ReadFile(hFile, buffRead, buffLength, &nRead, 0);
...然而,当我尝试重新打开管道来读取时,CreateFile调用会失败,因为“所有管道都很忙”。
我在这里错过了什么?
编辑.窥视很好,例如
DWORD nRead, nTotal, nLeft;
PeekNamedPipe(hPipe, buffRead, buffLength, &nRead, &nTotal, &nLeft);正确返回写入的数据。
备注:,这是对更大事物的概念的证明。不会涉及新的线程和进程。
发布于 2015-07-29 22:51:38
获得特定错误代码的原因是,您只创建了一个命名管道的实例,并且已经使用了它。(您可以通过第二次调用CreateNamedPipe创建一个新实例,也可以通过调用DisconnectNamedPipe重用现有实例。)
但是,根据您的评论,我相信您希望调用ReadFile来检索WriteFile调用所编写的数据,也就是说,您需要的是管道的同一个实例,而不是新的实例。
要做到这一点,请不要打开新句柄。使用现有的句柄,hPipe。
(请注意,每个管道实例都有两个端:服务器端和客户端。来自CreateNamedPipe的句柄总是指向服务器端,而来自CreateFile的句柄总是指向客户端。写入服务器端的数据只能从客户端读取,反之亦然。
发布于 2015-07-29 12:34:21
您正在尝试使用命名管道作为某种缓冲区-客户端连接到它,放置一些数据,然后断开,之后,其他客户端连接和检索这些数据。这是无效的方法,命名管道只是-一个管道,它有两个方面-服务器端和客户端,服务器和客户端可以通过它进行通信。通常的管道使用场景:
CreateNamedPipe函数创建命名管道;ConnectNamedPipe方法等待客户端连接;CreateFile API调用创建管道的一侧;ReadFile/WriteFile进行通信;DisconnectNamedPipe关闭,可以用ConnectNamedPipe重新激活。您可以在MSDN 这里中看到完整的示例。
发布于 2015-07-29 13:33:32
这是因为管道的两端都已经打开了(*).
第一个是用CreatePipe调用打开的,另一个是第一个CreateFile调用。您不应该尝试再打开一次管道,而应该简单地从hPipe句柄读取:
const char * pipeName = "\\\\.\\pipe\\pipe";
const char * buffWrite = "SOME TEXT";
unsigned buffLength = strlen(buffWrite);
char buffRead[1024];
DWORD nWritten, nRead;
HANDLE hPipe = CreateNamedPipe(pipeName,
PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 1024, 1024, 0, 0);
HANDLE hFile = CreateFile(pipeName, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
WriteFile(hFile, buffWrite, buffLength, &nWritten, 0);
CloseHandle(hFile);
ReadFile(hPipe, buffRead, buffLength, &nRead, 0); // nRead=9, buffRead="SOME TEXT"
...(*)您确实在PIPE_UNLIMITED_INSTANCES调用中为nMaxInstances参数指定了CreateNamedPipe,但由于您从未调用ConnectNamedPipe来创建其他端点,因此只允许一个CreateFile。
https://stackoverflow.com/questions/31700018
复制相似问题