例子---window平台下的管道使用

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;
}




下面是一个简单的例子,演示了如何在两个进程之间使用命名管道传递消息。 首先,我们需要创建一个命名管道,代码如下: ```c++ HANDLE hPipe; LPTSTR lpPipeName = TEXT("\\\\.\\pipe\\MyPipe"); hPipe = CreateNamedPipe(lpPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); if (hPipe == INVALID_HANDLE_VALUE) { // 处理错误 } ``` 在这个例子中,我们使用 `CreateNamedPipe` 函数创建了一个名为 `MyPipe` 的命名管道管道的访问模式为双向访问,类型为消息型管道,读取模式为消息读取模式,等待模式为默认等待模式。管道的实例数量为无限制,输入缓冲区大小和输出缓冲区大小均为1024字节。 接下来,我们在一个进程中向管道中写入消息: ```c++ DWORD dwWritten; char szMessage[] = "Hello, World!"; if (!ConnectNamedPipe(hPipe, NULL)) { // 处理错误 } if (!WriteFile(hPipe, szMessage, strlen(szMessage), &dwWritten, NULL)) { // 处理错误 } FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); ``` 在这个例子中,我们使用 `ConnectNamedPipe` 函数等待客户端连接管道。一旦客户端连接上管道,我们通过 `WriteFile` 函数将消息写入管道。最后,我们使用 `FlushFileBuffers` 函数和 `DisconnectNamedPipe` 函数断开管道连接。 在另一个进程中,我们可以从管道中读取消息,代码如下: ```c++ HANDLE hPipe; LPTSTR lpPipeName = TEXT("\\\\.\\pipe\\MyPipe"); hPipe = CreateFile(lpPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hPipe == INVALID_HANDLE_VALUE) { // 处理错误 } char szMessage[1024]; DWORD dwRead; if (!ReadFile(hPipe, szMessage, sizeof(szMessage), &dwRead, NULL)) { // 处理错误 } printf("Received message: %s\n", szMessage); CloseHandle(hPipe); ``` 在这个例子中,我们使用 `CreateFile` 函数连接到名为 `MyPipe` 的命名管道。一旦连接成功,我们可以使用 `ReadFile` 函数从管道中读取消息。最后,我们通过 `printf` 函数打印出收到的消息,并关闭管道连接。 这就是一个简单的例子,演示了如何在两个进程之间使用命名管道传递消息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值