进程间通信(命名管道)

/ win32+MFC / 没有评论 / 1982浏览

命令管道:管道名最多可达256个字符的长度。服务端和客户端能运行在不同的机器上。区别在管道命名,代码中有注释。

###服务端

  /*
服务端
*/

#include <iostream>
#include <windows.h>
#include <AtlConv.h>
using namespace std;

int main(int argc, char *argv[])
{
	//创建命名管道
	HANDLE hpipe;
	hpipe = CreateNamedPipe(L"\\\\.\\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';

	//弹出获得的数据    
	USES_CONVERSION;
	LPCWSTR str2;
	str2 = A2W(str);
	MessageBox(::GetConsoleWindow(), str2,L"NamedPipe_Server", MB_OK);
	::CloseHandle(hevent);
	::CloseHandle(hpipe);
	return 0;
}

###客户端

/*
客户端
*/

#include <iostream>
#include <windows.h>
#include <AtlConv.h>
using namespace std;

int main(int argc, char *argv[])
{
	if (!::WaitNamedPipe(L"\\\\.\\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(L"\\\\.\\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';

	//弹出获得的数据    
	USES_CONVERSION;
	LPCWSTR str2;
	str2 = A2W(str);
	MessageBox(::GetConsoleWindow(), str2, L"NamedPipe_Client", MB_OK);

	//重新写入管道数据
	strcpy_s(str, "hello server! (FORM Client)");
	WriteFile(hpipe, str, strlen(str), &NumberOfBytesWritten, NULL);
	::CloseHandle(hpipe);
	return 0;
}