C++ 进程间的通讯(一):简单的有名管道实现

进程间的通讯(一):简单的有名管道实现


一 管道简介

命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是命名管道可以在不相关的进程之间和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。
其优点是实现起来比较简单方便.
缺点是会使进程之间的代码耦合度增加.并且管道通信只适用于同一台主机上的进程之间通讯.

二 实现代码

Server Code:

#include "stdafx.h"
#include 
#include 
#include 

int main(int argc, _TCHAR* argv[])
{
	srand(time(NULL));

	char buf[256] = "";
	DWORD rlen = 0;
	HANDLE hPipe = CreateNamedPipe(
		TEXT("\\\\.\\Pipe\\mypipe"),						//管道名
		PIPE_ACCESS_DUPLEX,									//管道类型 
		PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT,	//管道参数
		PIPE_UNLIMITED_INSTANCES,							//管道能创建的最大实例数量
		0,													//输出缓冲区长度 0表示默认
		0,													//输入缓冲区长度 0表示默认
		NMPWAIT_WAIT_FOREVER,								//超时时间
		NULL);													//指定一个SECURITY_ATTRIBUTES结构,或者传递零值.
	if (INVALID_HANDLE_VALUE == hPipe)
	{
		printf("Create Pipe Error(%d)\n",GetLastError());
	}
	else
	{
		printf("Waiting For Client Connection...\n");
		if(ConnectNamedPipe(hPipe, NULL)==NULL)	//阻塞等待客户端连接。
		{
			printf("Connection failed!\n");
		}
		else
		{
			printf("Connection Success!\n");
		}

		while (true)
		{
			if(ReadFile(hPipe,buf,256,&rlen,NULL)==FALSE) //接受客户端发送过来的内容
			{			
				printf("Read Data From Pipe Failed!\n");
				break;
			}
			else
			{
				printf("From Client: data = %s, size = %d\n", buf, rlen);
				char wbuf[256] = "";
				sprintf(wbuf, "%s%d", wbuf, rand()%1000);
				DWORD wlen = 0;
				WriteFile(hPipe, wbuf, sizeof(wbuf), &wlen, 0);	//向客户端发送内容
				printf("To Client: data = %s, size = %d\n", wbuf, wlen);
				Sleep(1000);
			}
		}
		CloseHandle(hPipe);//关闭管道
	}

	system("PAUSE");
	return 0;
}


Clietn Code:

#include "stdafx.h"
#include 
#include 
#include 

int main(int argc, _TCHAR* argv[])
{
	srand(time(NULL));

	DWORD wlen = 0;
	Sleep(1000);//等待pipe的创建成功!

	BOOL bRet = WaitNamedPipe(TEXT("\\\\.\\Pipe\\mypipe"), NMPWAIT_WAIT_FOREVER);

	if (!bRet)
	{
		printf("connect the namedPipe failed!\n");
		return 0;
	}

	HANDLE hPipe=CreateFile(			//管道属于一种特殊的文件
		TEXT("\\\\.\\Pipe\\mypipe"),	//创建的文件名
		GENERIC_READ | GENERIC_WRITE,	//文件模式
		0,								//是否共享
		NULL,							//指向一个SECURITY_ATTRIBUTES结构的指针
		OPEN_EXISTING,					//创建参数
		FILE_ATTRIBUTE_NORMAL,			//文件属性(隐藏,只读)NORMAL为默认属性
		NULL);							//模板创建文件的句柄

	if (INVALID_HANDLE_VALUE == hPipe)
	{
		printf("open the exit pipe failed!\n");
	}
	else
	{
		while(true)
		{
			char buf[256] = "";
			sprintf(buf,"%s%d",buf,rand()%1000);
			if(WriteFile(hPipe,buf,sizeof(buf),&wlen,0)==FALSE)	//向服务器发送内容
			{
				printf("write to pipe failed!\n");
				break;
			}
			else
			{
				printf("To Server: data = %s, size = %d\n", buf, wlen);
				char rbuf[256] = "";
				DWORD rlen = 0;
				ReadFile(hPipe, rbuf, sizeof(rbuf), &rlen, 0);	//接受服务发送过来的内容
				printf("From Server: data = %s, size = %d\n", rbuf, rlen);
			}
			Sleep(1000);
		}
		CloseHandle(hPipe);//关闭管道
	}

	system("PAUSE");
	return 0;
}


你可能感兴趣的:(C/C++)