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 函数文档说 Handle 参数可以来自服务器端 (CreateNamedPipe) 或客户端 (CreateFile)。
hNamedPipe [in] A handle to the pipe. This parameter can be a handle
to a named pipe instance, as returned by the CreateNamedPipe or
CreateFile function, or it can be a handle to the read end of an
anonymous pipe, as returned by the CreatePipe function. The handle
must have GENERIC_READ access to the pipe.
当我给函数一个来自 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)] = '[=10=]'; // 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(服务器句柄)而不是 pC(客户端句柄)提供给 PeekNamedPipe,则可用字节数始终为 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.
来自documentation for PeekNamedPipe,右上角的备注:
The PeekNamedPipe function is similar to the ReadFile function
您不能使用 ReadFile 读取您发送到管道另一端的数据,因此您不能使用 PeekNamedPipe 获取有关您发送到管道另一端的数据的信息要么。
如果您想知道管道另一端的进程读取了多少传出数据,您需要在数据协议中构建某种反馈。
PeekNamedPipe 函数文档说 Handle 参数可以来自服务器端 (CreateNamedPipe) 或客户端 (CreateFile)。
hNamedPipe [in] A handle to the pipe. This parameter can be a handle to a named pipe instance, as returned by the CreateNamedPipe or CreateFile function, or it can be a handle to the read end of an anonymous pipe, as returned by the CreatePipe function. The handle must have GENERIC_READ access to the pipe.
当我给函数一个来自 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)] = '[=10=]'; // 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(服务器句柄)而不是 pC(客户端句柄)提供给 PeekNamedPipe,则可用字节数始终为 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.
来自documentation for PeekNamedPipe,右上角的备注:
The PeekNamedPipe function is similar to the ReadFile function
您不能使用 ReadFile 读取您发送到管道另一端的数据,因此您不能使用 PeekNamedPipe 获取有关您发送到管道另一端的数据的信息要么。
如果您想知道管道另一端的进程读取了多少传出数据,您需要在数据协议中构建某种反馈。