1. 程式人生 > >例子---window平臺下的管道使用

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