这是第一个应用程序中的“PipeServer”:
// Open Pipe and wait until ControlProgram is connecting
Pipe.Out = INVALID_HANDLE_VALUE;
const wchar_t *data = L"*** Hello Pipe World ***";
DWORD numBytesWritten = 0;
DWORD timerinit = GetTickCount();;
while (1)
{
DWORD timer = GetTickCount();
if ((timer - timerinit) > 1000)
{
timerinit = timer;
if (ConnectNamedPipe(Pipe.Out, NULL))
{
WriteFile(
Pipe.Out, // handle to our outbound pipe
data, // data to send
wcslen(data) * sizeof(wchar_t), // length of data to send (bytes)
&numBytesWritten, // will store actual amount of data sent
NULL // not using overlapped IO
);
}
else
{
CloseHandle(Pipe.Out);
Pipe.Out = INVALID_HANDLE_VALUE;
do
{
Pipe.Out = CreateNamedPipeW(
L"\\\\.\\pipe\\mypipe", // name of the pipe
PIPE_ACCESS_OUTBOUND, // 1-way pipe -- send only
PIPE_TYPE_BYTE, // send data as a byte stream
1, // only allow 1 instance of this pipe
0, // no outbound buffer
0, // no inbound buffer
0, // use default wait time
NULL // use default security attributes
);
}
while (Pipe.Out == INVALID_HANDLE_VALUE);
}
}
}
这是“PipeClient”应用程序:
///// CLIENT PROGRAM /////
#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, const char **argv)
{
wcout << "Connecting to pipe..." << endl;
// Open the named pipe
// Most of these parameters aren't very relevant for pipes.
HANDLE pipe = CreateFileW(
L"\\\\.\\pipe\\mypipe",
GENERIC_READ, // only need read access
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (pipe == INVALID_HANDLE_VALUE)
{
wcout << "Failed to connect to pipe." << endl;
// look up error code here using GetLastError()
system("pause");
return 1;
}
wcout << "Reading data from pipe..." << endl;
while (1)
{
// The read operation will block until there is data to read
wchar_t buffer[128];
DWORD numBytesRead = 0;
BOOL result = ReadFile(
pipe,
buffer, // the data from the pipe will be put here
127 * sizeof(wchar_t), // number of bytes allocated
&numBytesRead, // this will store number of bytes actually read
NULL // not using overlapped IO
);
if (result)
{
buffer[numBytesRead / sizeof(wchar_t)] = '\0'; // null terminate the string
wcout << "Number of bytes read: " << numBytesRead << endl;
wcout << "Message: " << buffer << endl;
FlushFileBuffers(pipe);
}
else
{
wcout << "Failed to read data from the pipe." << endl;
wcout << result << endl;
CloseHandle(pipe);
break;
}
}
// Close our pipe handle
wcout << "Done." << endl;
system("pause");
return 0;
}
服务器应等待客户端连接,然后每 1 秒发送一次定义的消息。
客户端应该能够随时启动/重新启动。
但是每当我启动客户端时,它都会收到一次消息,然后在从管道读取时退出并出错。
结果返回 0。
更新(对于那些想知道它现在如何工作的人)
这是“更新”的 PipeServer 代码:
// Open Pipe and wait until ControlProgram is connecting
Pipe.Out = INVALID_HANDLE_VALUE;
DWORD numBytesWritten = 0;
DWORD timerinit = GetTickCount();
bool connected = false;
bool writesucc = false;
bool initial = true;
while (1)
{
DWORD timer = GetTickCount();
wchar_t data[100];
if (!initial)
{
swprintf_s(data, 100, L"Time: %d", timer); // use L"" prefix for wide chars
}
else
{
swprintf_s(data, 100, L"Welcome from your Pipe Server"); // use L"" prefix for wide chars
}
if ((timer - timerinit) > 1000)
{
timerinit = timer;
if (!connected)
{
connected = ConnectNamedPipe(Pipe.Out, NULL);
}
if (connected)
{
writesucc = WriteFile(
Pipe.Out, // handle to our outbound pipe
data, // data to send
wcslen(data) * sizeof(wchar_t), // length of data to send (bytes)
&numBytesWritten, // will store actual amount of data sent
NULL // not using overlapped IO
);
if (writesucc) initial = false;
}
if ((!writesucc) || (Pipe.Out == INVALID_HANDLE_VALUE) || (!connected))
{
initial = true;
CloseHandle(Pipe.Out);
Pipe.Out = INVALID_HANDLE_VALUE;
do
{
Pipe.Out = CreateNamedPipeW(
L"\\\\.\\pipe\\mypipe", // name of the pipe
PIPE_ACCESS_OUTBOUND, // 1-way pipe -- send only
PIPE_TYPE_BYTE, // send data as a byte stream
1, // only allow 1 instance of this pipe
0, // no outbound buffer
0, // no inbound buffer
0, // use default wait time
NULL // use default security attributes
);
}
while (Pipe.Out == INVALID_HANDLE_VALUE);
}
}
}