1.匿名管道 (主要用于父子进程的通信)
父进程
#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, char *argv[])
{
HANDLE hInRead;
HANDLE hInWrite;
HANDLE hOutRead;
HANDLE hOutWrite;
SECURITY_ATTRIBUTES sa;
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = true;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
if (!CreatePipe(&hInRead, &hInWrite, &sa, 0)) {
cout << "CreatePipe1 error!" << endl;
exit(-1);
}
if (!CreatePipe(&hOutRead, &hOutWrite, &sa, 0)) {
cout << "CreatePipe2 error!" << endl;
exit(-1);
}
STARTUPINFO startupInfo;
memset(&startupInfo, 0, sizeof(STARTUPINFO));
startupInfo.cb = sizeof(STARTUPINFO);
startupInfo.dwFlags |= STARTF_USESTDHANDLES;
startupInfo.hStdInput = hInRead;
startupInfo.hStdOutput = hOutWrite;
startupInfo.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
PROCESS_INFORMATION proInfo;
memset(&proInfo, 0, sizeof(PROCESS_INFORMATION));
if (!CreateProcess("../Debug/anonymous_pipe_child.exe", //子进程的路径
NULL,
NULL,
NULL,
true,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&startupInfo,
&proInfo)) {
cout << "create process error!";
exit(-1);
}
::CloseHandle(proInfo.hThread);
::CloseHandle(proInfo.hProcess);
::CloseHandle(hInRead);
::CloseHandle(hOutWrite);
//写入数据到子进程
char str[50] = "hello child! (FORM father)";
DWORD NumberOfBytesWritten;
WriteFile(hInWrite, str, strlen(str), &NumberOfBytesWritten, NULL);
memset(str, 0, sizeof(str));
ReadFile(hOutRead, str, sizeof(str), &NumberOfBytesWritten, NULL);
str[NumberOfBytesWritten] = '\0';
//弹出获得的数据
MessageBox(::GetConsoleWindow(), str, "anonymous_pipe", MB_OK);
::CloseHandle(hOutRead);
::CloseHandle(hInWrite);
return 0;
}
#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, char *argv[])
{
//获得标准输入输出句柄
HANDLE hRead = ::GetStdHandle(STD_INPUT_HANDLE);
HANDLE hWrite = ::GetStdHandle(STD_OUTPUT_HANDLE);
char str[50];
DWORD NumberOfBytesWritten;
memset(str, 0, sizeof(str));
ReadFile(hRead, str, sizeof(str), &NumberOfBytesWritten, NULL);
str[NumberOfBytesWritten] = '\0';
MessageBox(::GetConsoleWindow(), str, "anonymous_pipe_child", MB_OK);
strcpy(str, "hello father! (FORM child)");
WriteFile(hWrite, str, strlen(str), &NumberOfBytesWritten, NULL);
::CloseHandle(hRead);
::CloseHandle(hWrite);
return 0;
}
2.命名管道 (可以用于本机上不同进程之间的通信,也可以用于远程机器上进程的通信)
服务端
#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, char *argv[])
{
//创建命名管道
HANDLE hpipe;
hpipe = CreateNamedPipe("\\\\.\\pipe\\NewPipe",
PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
0,
PIPE_UNLIMITED_INSTANCES,
1024,
1024,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
if ( INVALID_HANDLE_VALUE == hpipe) {
cout << "CreateNamedPipe error!" << endl;
exit(-1);
}
HANDLE hevent;
hevent = ::CreateEvent(NULL, true, false, NULL); // 人工重置
OVERLAPPED overlap;
memset(&overlap, 0, sizeof(OVERLAPPED));
overlap.hEvent = hevent;
if (!ConnectNamedPipe(hpipe, &overlap)) {
if (ERROR_IO_PENDING != ::GetLastError()) {
cout << "CreateNamedPipe error!" << endl;
exit(-1);
}
}
// 当客户端连接时,事件变为有信号
if (WAIT_FAILED == WaitForSingleObject(hevent,INFINITE)) {
cout << "WaitForSingleObject error!" << endl;
exit(-1);
}
//写入数据到子进程
char str[50] = "hello client! (FORM Server)";
DWORD NumberOfBytesWritten;
WriteFile(hpipe, str, strlen(str), &NumberOfBytesWritten, NULL);
memset(str, 0, sizeof(str));
ReadFile(hpipe, str, sizeof(str), &NumberOfBytesWritten, NULL);
str[NumberOfBytesWritten] = '\0';
//弹出获得的数据
MessageBox(::GetConsoleWindow(), str, "NamedPipe_Server", MB_OK);
::CloseHandle(hevent);
::CloseHandle(hpipe);
return 0;
}
客户端
#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, char *argv[])
{
if (!::WaitNamedPipe("\\\\.\\pipe\\NewPipe", NMPWAIT_USE_DEFAULT_WAIT)) {
cout << "WaitNamedPipe error1" << endl;
exit(-1);
}
// \\.\pipe\name 表示本机上的命名管道
// \\192.168.1.6\pipe\name 打开ip为192.168.1.6的远程的命名管道
HANDLE hpipe;
hpipe = ::CreateFile("\\\\.\\pipe\\NewPipe",
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE == hpipe) {
cout << "Open NamedPipe error!" << endl;
exit(-1);
}
//写入数据到子进程
char str[50];
DWORD NumberOfBytesWritten;
memset(str, 0, sizeof(str));
ReadFile(hpipe, str, sizeof(str), &NumberOfBytesWritten, NULL);
str[NumberOfBytesWritten] = '\0';
//弹出获得的数据
MessageBox(::GetConsoleWindow(), str, "NamedPipe_Client", MB_OK);
strcpy(str, "hello server! (FORM Client)");
WriteFile(hpipe, str, strlen(str), &NumberOfBytesWritten, NULL);
::CloseHandle(hpipe);
return 0;
}