2015-09-06 56 views
2

如果我运行管道客户端来测试GetNamedPipeHandleState函数,我得到错误Error 87: The parameter is incorrect命名管道和“GetNamedPipeHandleState”

这里我的代码,客户机和服务器:

#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; 
} 

这是项目,我做的克利翁。可以作为“应用程序客户端”或“应用程序服务器”运行。

错误的原因是什么?

+1

您在错误的时间调用'GetLastError'。 Windows API调用失败后,您将不得不立即调用**。您致电'CloseHandle'的电话可能会覆盖您感兴趣的错误代码。 – IInspectable

+1

好的,明白了,谢谢 – Crostopher

+0

@IInspectable:即使是这样的情况,CloseHandle()应该不会将错误代码重置为87代码中的'hNamedPipe'在该点不是无效的。 –

回答

1

As documented

lpMaxCollectionCount [out, optional]

[...] This parameter must be NULL [...] if client and server processes are on the same computer.

lpCollectDataTimeout [out, optional]

[...] This parameter must be NULL [...] if client and server processes are on the same computer.

lpUserName [out, optional]

[...] This parameter must be NULL if the specified pipe handle is to the client end of a named pipe.

一旦这些参数的所有三个已设置为NULL,呼叫作品。