命名管道" GetNamedPipeHandleState"

时间:2015-09-06 09:59:08

标签: c++ winapi named-pipes

如果我运行管道客户端来测试GetNamedPipeHandleState函数,则会收到错误Error 87: The parameter is incorrect

这是我的代码,包括客户端和服务器:

#include <iostream>
#include <stdio.h>
#include <conio.h>
#include "windows.h"

using namespace std;

void showError(const char *text) {
    char Buf[256];
    DWORD errNo = GetLastError();
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), Buf,
                  sizeof(Buf), NULL);
    fprintf(stdout, "%s, error %d, %s\nPress any key to Exit", text, (int) errNo, Buf);
    _getch();
}

int client_GetNamedPipeHandleState() {

    DWORD dwState;
    DWORD dwCurInstances;
    DWORD dwMaxCollectionCount;
    DWORD dwCollectDataTimeout;
    TCHAR chUserName[255];

    char pipeName[] = "\\\\.\\pipe\\demo_pipe";
    HANDLE hNamedPipe;

    hNamedPipe = CreateFileA(pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
                             NULL);

    if (hNamedPipe == INVALID_HANDLE_VALUE) {
        showError("Create File failed");
        return 0;
    }

    if (!GetNamedPipeHandleState(
        hNamedPipe, &dwState, &dwCurInstances, &dwMaxCollectionCount,&dwCollectDataTimeout, chUserName, 255)) {
        //hNamedPipe, &dwState, &dwCurInstances, NULL, NULL, NULL, 0)) {
        CloseHandle(hNamedPipe);
        showError("get state failed");
        return 0;
    }

    cout << "State: " << dwState << ", ";
    switch (dwState) {
        case (PIPE_NOWAIT):
            cout << "PIPE_NOWAIT" << endl;
            break;
        case (PIPE_READMODE_MESSAGE):
            cout << "PIPE_READMODE_MESSAGE" << endl;
            break;
        case (PIPE_NOWAIT | PIPE_READMODE_MESSAGE):
            cout << "PIPE_NOWAIT and PIPE_READMODE_MESSAGE" << endl;
            break;
        default:
            cout << "Unknown state." << endl;
            break;
    }

    cout << "Current instances: " << dwCurInstances << endl
    << "Max collection count: " << dwMaxCollectionCount << endl
    << "Collection data timeout: " << dwCollectDataTimeout << endl
    << "User name: " << chUserName << endl;

    CloseHandle(hNamedPipe);
    cout << "Press any key to exit.";
    cin.get();
    return 0;
}

int server() {
    HANDLE hNamedPipe;
    DWORD dwBytesRead;
    DWORD dwBytesWrite;
    char pchMessage[80];
    DWORD nMessageLength;

    hNamedPipe = CreateNamedPipeA(
            "\\\\.\\pipe\\demo_pipe",
            PIPE_ACCESS_DUPLEX,
            PIPE_TYPE_MESSAGE | PIPE_WAIT,
            1,
            0,
            0,
            INFINITE,
            NULL
    );

    if (hNamedPipe == INVALID_HANDLE_VALUE) {
        showError("Create named pipe failed");
        return 0;
    }

    printf("Waiting client...\n");
    if (!ConnectNamedPipe(hNamedPipe, NULL)) {
        showError("Connect to name pipe failed");
        CloseHandle(hNamedPipe);
        return 0;
    }
    if (!ReadFile(hNamedPipe, pchMessage, sizeof(pchMessage), &dwBytesRead, NULL)) {
        CloseHandle(hNamedPipe);
        showError("Read pipe failed");
        return 0;
    }

    printf("The server received the message from client: %s\n", pchMessage);
    cout << "Input a string: ";
    cin.getline(pchMessage, 80);
    nMessageLength = strlen(pchMessage) + 1;

    //Answer to client
    if (!WriteFile(hNamedPipe, pchMessage, nMessageLength, &dwBytesWrite, NULL)) {
        CloseHandle(hNamedPipe);
        showError("Write file failed.");
        return 0;
    }
    printf("The Server send the message to the client: %s\n", pchMessage);
    CloseHandle(hNamedPipe);
    printf("Press any key to exit");
    cin.get();
    return 0;
}

int main(int argc, char *argv[]) {
    if (argc == 1) return 0;

    if (!strcmp(argv[1], "client")) {
        client_GetNamedPipeHandleState();
    }

    if (!strcmp(argv[1], "server")) {
        server();
    }

    return 0;
}

这是我在Clion制作的项目。可以作为&#34; app client&#34;或者&#34; app server&#34;。

错误的原因是什么?

1 个答案:

答案 0 :(得分:1)

As documented

  

lpMaxCollectionCount [out,optional]

     

[...]如果客户端和服务器进程在同一台计算机上,则此参数必须为NULL [...]。

     

lpCollectDataTimeout [out,optional]

     

[...]如果客户端和服务器进程在同一台计算机上,则此参数必须为NULL [...]。

     

lpUserName [out,optional]

     

[...]如果指定的管道句柄是命名管道的客户端,则此参数必须为NULL。

一旦所有这三个参数都设置为NULL,呼叫就会起作用。