简体   繁体   English

无法打开 Windows 命名管道进行写入?

[英]Can't open Windows Named Pipe for writing?

I don't understand why I can't even open a named pipe for writing that I created in another process.我不明白为什么我什至无法打开我在另一个进程中创建的用于写入的命名管道。

I get the error我收到错误

231 (All pipe instances are busy). 231(所有管道实例都忙)。

The writer (client):作者(客户):

#include "Windows.h"
#include <stdio.h>
#include <errno.h>

int main()
{
    HANDLE hpipe;
    DWORD written;
    char msg[] = "play asdf.wav";

    hpipe = CreateFileA("\\\\.\\pipe\\isp-control",
               GENERIC_WRITE | GENERIC_READ,
               0, NULL, OPEN_EXISTING, 0, NULL);

    if (hpipe != INVALID_HANDLE_VALUE)
    {
      WriteFile(hpipe, msg, strlen(msg) + 1, &written, NULL);
      printf("wrote %d bytes of %d: '%s'\n", written, strlen(msg) + 1, msg);

      CloseHandle(hpipe);
    }
    else
    {
      printf("error %d opening pipe (handle %d)\n", GetLastError(), (int) hpipe);
      return 1;
    }

    return 0;
}

The reader (server) has before created the pipe like this (note the 4 instances, so one should be free, isn't it?)读者(服务器)之前已经创建了这样的管道(注意 4 个实例,所以一个应该是免费的,不是吗?)

hpipe_ = CreateNamedPipeA("\\\\.\\pipe\\isp-control",
             PIPE_ACCESS_DUPLEX,
             PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
             4, // number of instances
             1024 * 16, // output buffer size
             65535,  // input size
             2000, // default timeout ms 
             NULL);

and then uses PeekNamedPipe to see if there's data to be read with ReadFile or send a timeout.然后使用PeekNamedPipe查看是否有数据要使用ReadFile读取或发送超时。

the 4-th parameter of CreateNamedPipe - nMaxInstances - this is The maximum number of instances that can be created for this pipe. CreateNamedPipe的第 4 个参数 - nMaxInstances - 这是可以为此管道创建的最大实例数。

so this is not instance count created in single call, but maximum count which can be created.所以这不是在单次调用中创建的实例计数,而是可以创建的最大计数。 single call to CreateNamedPipe always create one (1) instance of pipe.CreateNamedPipe单个调用始终创建一 (1) 个管道实例。 if you want have 4 instance - you need call CreateNamedPipe 4 time.如果你想要 4 个实例 - 你需要调用CreateNamedPipe 4 次。 also initially pipe created in listening state, so client can just connect to it by call CreateFile .管道最初也是在侦听状态下创建的,因此客户端可以通过调用CreateFile连接到它。 but after connection is broken (because client close self handle) and you want accept new client connections for the same pipe instance - you need call DisconnectNamedPipe and then ConnectNamedPipe - only after this new client can again connect to the same pipe instance.但是在连接中断后(因为客户端关闭了自己的句柄)并且你想接受同一个管道实例的新客户端连接 - 你需要调用DisconnectNamedPipe然后ConnectNamedPipe - 只有在这个新客户端可以再次连接到同一个管道实例之后。

but anyway, even if you create only single pipe instance, by single call CreateNamedPipeA - first client can connect to it.但无论如何,即使您只创建单个管道实例,通过单次调用CreateNamedPipeA - 第一个客户端也可以连接到它。 error 231 - i guess that real source of error is STATUS_PIPE_NOT_AVAILABLE ( An instance of a named pipe cannot be found in the listening state ) - you can check this by call RtlGetLastNtStatus() after CreateFile fail instead GetLastError() say that pipe name is valid, no problems with access, but somebody already connect (may be already disconnect) to pipe - never first call to CreateFile return this error错误 231 - 我猜真正的错误来源是STATUS_PIPE_NOT_AVAILABLE在侦听状态中找不到命名管道的实例) - 您可以在CreateFile失败后通过调用RtlGetLastNtStatus()来检查这一点,而不是GetLastError()说管道名称有效,访问没有问题,但有人已经连接(可能已经断开连接)到管道 - 永远不会第一次调用CreateFile返回此错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM