代码之家  ›  专栏  ›  技术社区  ›  Guett31

PeekNamedPipe无法提供正确的可用字节数,只有当句柄来自客户端时才有效

  •  -1
  • Guett31  · 技术社区  · 8 年前

    PeekNamedPipe函数文档指出句柄参数可以来自服务器端(CreateNamedPibe)或客户端(CreateFile)。

    hNamedPipe[在]管道的手柄。此参数可以是句柄 CreateFile函数,或者它可以是 匿名管道,由CreatePipe函数返回。把手

    以下代码有效:

    #include <iostream>
    #include <windows.h>
    using namespace std;
    
    int main(int argc, const char **argv)
    {
        wcout << "Creating an instance of a named pipe..." << endl;
    
        // Create a pipe to send data
        HANDLE pS = CreateNamedPipe(L"\\\\.\\pipe\\my_pipe", PIPE_ACCESS_DUPLEX, 0, 1, 100, 100, 0, NULL);
    
        // Open the named pipe
        HANDLE pC = CreateFile(L"\\\\.\\pipe\\my_pipe", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    
        if (pC == INVALID_HANDLE_VALUE)
        {
            wcout << "Failed to connect to pipe." << endl;
            return 1;
        }
    
        wcout << "Test PeekNamedPipe #1." << endl;
        DWORD PipeByteNum = 0;
        BOOL res = PeekNamedPipe(pC, NULL, 0, NULL, &PipeByteNum, NULL);
        if(!res)
        {
              wcout << "PeekNamedPipe() - failed." << endl;
              return 1;
        }
        wcout << " - Number of bytes in pipe: " << PipeByteNum << endl << endl;
    
        wcout << "Sending data to pipe..." << endl;
    
       const wchar_t *data = L"Hello Pipe World";
       DWORD numBytesWritten = 0;
       BOOL result = WriteFile(pS, data, wcslen(data) * sizeof(wchar_t), &numBytesWritten, NULL);
    
        if (result)
          wcout << "Number of bytes sent: " << numBytesWritten << endl;
        else
        {
          wcout << "Failed to send data." << endl;
          return 1;
        }
    
        wcout << "Test PeekNamedPipe #2." << endl;
        PipeByteNum = 0;
        res = PeekNamedPipe(pC, NULL, 0, NULL, &PipeByteNum, NULL);
        if(!res)
        {
              wcout << "PeekNamedPipe() - failed." << endl;
              return 1;
        }
        wcout << " - Number of bytes in pipe: " << PipeByteNum << endl << endl;
    
        wcout << "Reading data from pipe..." << endl;
    
        // The read operation will block until there is data to read
        wchar_t buffer[128];
        DWORD numBytesRead = 0;
        result = ReadFile(pC, buffer, 5 * sizeof(wchar_t), &numBytesRead, NULL);
    
        if (result)
        {
          buffer[numBytesRead / sizeof(wchar_t)] = '\0'; // null terminate the string
          wcout << "Number of bytes read: " << numBytesRead << endl;
          wcout << "Message: " << buffer << endl;
        }
        else
        {
          wcout << "Failed to read data from the pipe." << endl;
          return 1;
        }
    
        wcout << "Test PeekNamedPipe #3." << endl;
        PipeByteNum = 0;
        res = PeekNamedPipe(pC, NULL, 0, NULL, &PipeByteNum, NULL);
        if(!res)
        {
              wcout << "PeekNamedPipe() - failed." << endl;
              return 1;
        }
        wcout << " - Number of bytes in pipe: " << PipeByteNum << endl << endl;
    
        // Close client.
        CloseHandle(pC);
        wcout << "Done with client." << endl;
    
        // Close the pipe.
        CloseHandle(pS);
        wcout << "Done with server." << endl;
    
        return 0;
    }
    

    Creating an instance of a named pipe...
    Test PeekNamedPipe #1.
     - Number of bytes in pipe: 0
    
    Sending data to pipe...
    Number of bytes sent: 32
    Test PeekNamedPipe #2.
     - Number of bytes in pipe: 32
    
    Reading data from pipe...
    Number of bytes read: 10
    Message: Hello
    Test PeekNamedPipe #3.
     - Number of bytes in pipe: 22
    
    Done with client.
    Done with server.
    

    现在,如果我给PeekNamedPipe提供pS(服务器句柄)而不是pC(客户端句柄),则可用字节数始终为0。

    输出变为:

    Creating an instance of a named pipe...
    Test PeekNamedPipe #1.
     - Number of bytes in pipe: 0
    
    Sending data to pipe...
    Number of bytes sent: 32
    Test PeekNamedPipe #2.
     - Number of bytes in pipe: 0
    
    Reading data from pipe...
    Number of bytes read: 10
    Message: Hello
    Test PeekNamedPipe #3.
     - Number of bytes in pipe: 0
    
    Done with client.
    Done with server.
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   Harry Johnston    8 年前

    documentation for PeekNamedPipe, 在评论的顶部:

    PeekNamedPipe函数类似于ReadFile函数

    您不能使用ReadFile读取发送到管道另一端的数据,因此也不能使用PeekNamedPipe获取发送到管道的另一端的信息。

    如果您想知道管道另一端的进程读取了多少传出数据,则需要在数据协议中构建某种反馈。