我试图在命名管道中写入并回读同样的事情。请考虑以下代码段(为简洁起见,将删除错误处理):
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时,调用失败,并且#34;所有管道都忙。&#34;
我在这里缺少什么?
修改 偷看工作正常,即
DWORD nRead, nTotal, nLeft;
PeekNamedPipe(hPipe, buffRead, buffLength, &nRead, &nTotal, &nLeft);
正确返回书面数据。
REMARK。 这是更大的概念的证明。不会涉及新的线程和流程。
答案 0 :(得分:2)
您获取该特定错误代码的原因是您只创建了一个命名管道实例,并且您已经使用过它。 (您可以通过再次调用CreateNamedPipe
来创建新实例,也可以通过调用DisconnectNamedPipe
来重用现有实例。)
但是,根据您的评论,我相信您希望调用ReadFile来检索由WriteFile调用所写的数据,即您需要管道的相同实例,而不是新的。
为此,请勿打开新手柄。使用现有句柄hPipe
。
(注意每个管道实例有两端;服务器端和客户端.AdigNamedPipe的句柄总是到服务器端,CreateFile的句柄总是到客户端。写入服务器端的数据只能从客户端读取,反之亦然。)
答案 1 :(得分:1)
您正在尝试使用命名管道作为某种缓冲区 - 客户端连接到它,放置一些数据,然后断开连接,之后其他客户端连接并检索此数据。这是无效的方法,命名管道只是 - 一个管道,它有两个方面 - 服务器端和客户端,服务器和客户端可以通过它沟通。通常的管道使用场景:
CreateNamedPipe
函数创建命名管道; ConnectNamedPipe
方法等待客户端连接; CreateFile
API调用创建管道的一面; ReadFile/WriteFile
; DisconnectNamedPipe
,可以使用ConnectNamedPipe
重新启用。您可以在MSDN here中看到完整的示例。
答案 2 :(得分:0)
这是因为管道的两端都已经打开(*)......
首先使用CreatePipe调用打开,另一个使用第一个CreateFile调用。您不应该尝试再打开一次管道,而只需从hPipe HANDLE中读取:
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
来创建其他端点,因此只有一个{{1}被允许。