创建命名管道错误

时间:2017-12-21 06:16:41

标签: c++ windows winapi named-pipes

我正在创建一个命名管道并使用一个函数来执行此操作。这是代码:

HANDLE              tProviderPipe(INVALID_HANDLE_VALUE);
SECURITY_ATTRIBUTES tSecurityAttributes;

tSecurityAttributes.nLength = sizeof(tSecurityAttributes);
tSecurityAttributes.bInheritHandle = FALSE;
tSecurityAttributes.lpSecurityDescriptor = NULL;
while (1)
{
    tProviderPipe = ::CreateNamedPipe(L"\\\\.\\pipe\\MyPipe",
                                      PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
                                      PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
                                      1,
                                      128,
                                      128,
                                      5000,
                                      &tSecurityAttributes);

    if (INVALID_HANDLE_VALUE != tProviderPipe)
    {
        DWORD lLastStatus(GetLastError());
        OHTRACE(Trace::eTAlways, L"Pipe Status: " << (unsigned int)lLastStatus);
        break;
    }
    if (ERROR_PIPE_BUSY != GetLastError())
    {
        DWORD lLastStatus(GetLastError());
        OHTRACE(Trace::eTAlways, L"Pipe Status: " << (unsigned int)lLastStatus);
        break;
    }
    if (!WaitNamedPipe(L"MyPipe", 20000))
    {
        DWORD lLastStatus(GetLastError());
        OHTRACE(Trace::eTAlways, L"WPipe Status: " << (unsigned int)lLastStatus);
    }

当调用此函数时,管道创建失败,错误代码为231(即管道忙)。我不明白为什么管道繁忙以及创建管道的正确方法是什么?在开始创建管道之前,应该检查和预检查的内容是什么?

1 个答案:

答案 0 :(得分:6)

你展示的代码都错了。

此检查:

if (INVALID_HANDLE_VALUE != tProviderPipe)

需要使用==代替!=。如果CreateNamedPipe() 成功,您的代码就会失败。

此检查:

if (ERROR_PIPE_BUSY != GetLastError())

需要删除。首先,它在错误的地方。 GetLastError()仅在CreateNamedPipe() 失败时才有效。完成上述==修正后,GetLastError()ERROR_PIPE_BUSY成功后永远不会是CreateNamedPipe()(或任何其他有意义的值)。其次,如果您将其移动到正在检查if的{​​{1}},那么它就会变得多余,因为它记录了已经记录在那里的相同信息。

此检查:

tProviderPipe

还需要删除。首先,您传递的是错误的管道名称格式。其次,它是在命名管道客户端之前调用if (!WaitNamedPipe(L"MyPipe", 20000)) (或CreateFile()失败并CreateFile())。不要在命名管道服务器中调用它。您打算调用ConnectNamedPipe(),等待客户端连接到您正在创建的服务器管道。

请查看MSDN上的named pipe server examples

尝试更像这样的东西:

ERROR_PIPE_BUSY