PeeknamedPipe在服务器给出句柄时不能给出正确数量的字节,只有在句柄来自客户端时才能起作用

PeekNamedPipe cannot give correct number of bytes available when given a Handle from the server, only works when the Handle come from the client

本文关键字:句柄 起作用 客户端 不能 服务器 PeeknamedPipe 字节      更新时间:2023-10-16

peeknamedPipe函数文档说句柄参数可以来自服务器端(CreateNamedPipe)或客户端(CreateFile)。

hnamedPipe [in]管道的手柄。此参数可以是一个句柄 到命名的管子实例,如CreateNamedPipe返回或 CreateFile函数,也可以是读取末端的处理 匿名管,由CreatePipe函数返回。手柄 必须具有对管道的通用访问。

当我将功能从CreateNamedPipe带来一个句柄时,无论管道实际包含什么,我总是会获得0个字节数。

以下代码有效:

#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)] = ''; // 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.

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

oftpout变为:

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.

从peeknamedpipe的文档中,就在备注的顶部:

peeknamedPipe函数与ReadFile函数相似

您无法使用ReadFile读取已发送到管道另一端的数据,因此您也不能使用PeeknamedPipe获取有关已发送到管道另一端的数据的信息。

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