使用管道实现一对多进程通信

使用管道实现一对多进程通信
前言

在使用管道进行进程间通信,这里实现客户端发送两个参数,服务端接收两个参数,将处理过的结果返回.
服务端 server.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

#define SIZE 4096
//最大连接数
#define MAX_CONNECT 128
//线程数量
#define THREADCOUNT 8
//管道名称
char pipename[32] = "\\\\.\\Pipe\\pipe_server";

typedef struct info
{
	HANDLE hthread;			//线程句柄
	HANDLE hpipe;			//管道句柄
	HANDLE hevent;			//事件句柄
}PIPE_INFO;

PIPE_INFO pipeList[MAX_CONNECT];

DWORD WINAPI func(void *p)
{
	DWORD nread = 0;
	DWORD nwrite = 0;
	DWORD nbyte = 0;
	char buf[SIZE] = { 0 };
	PIPE_INFO currentPipe = *(PIPE_INFO *)p;

	OVERLAPPED overlap = { 0,0,0,0,currentPipe.hevent };
	while (1)
	{
		//将buf数据清零
		memset(buf, 0, sizeof(buf));
		//连接 信息写入overlap中
		ConnectNamedPipe(currentPipe.hpipe, &overlap);
		//等待
		WaitForSingleObject(currentPipe.hevent, INFINITE);
		//检测io是否完成,完成的话就停止+
		if (!GetOverlappedResult(currentPipe.hpipe, &overlap, &nbyte, TRUE))
		{
			break;
		}
		//将内容读取buf数组中
		if (!ReadFile(currentPipe.hpipe, buf, SIZE, &nread, NULL))
		{
			printf("read failed!\n");
			break;
		}
		//将buf解析
		int numA = 0;
		int numB = 0;
		sscanf(buf, "%d %d", &numA, &numB);
		//将buf的内容重置为0
		memset(buf, 0, sizeof(buf));
		//将解析后的内容处理
		sprintf(buf, "%d", numA + numB);
		//将内容进行回写
		WriteFile(currentPipe.hpipe, buf, sizeof(buf), &nwrite, NULL);
		//断开管道
		DisconnectNamedPipe(currentPipe.hpipe);
	}
	return 1;
}

void start()
{
	for (int i = 0; i < THREADCOUNT; i++)
	{
		//创建管道
		pipeList[i].hpipe = CreateNamedPipeA(
			pipename,
			PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
			PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
			THREADCOUNT,
			0,						//缓冲区设置为0
			0,						//缓冲区设置为0
			1000,						//设置超时为1秒钟	
			NULL
		);
		if (pipeList[i].hpipe == INVALID_HANDLE_VALUE)
		{
			printf("%d创建失败!\n", i);
			break;
		}
		//创建事件
		pipeList[i].hevent = CreateEventA(NULL, FALSE, FALSE, FALSE);
		//创建线程
		pipeList[i].hthread = CreateThread(NULL, 0, func, &pipeList[i], 0, NULL);
	}
	printf("server start...\n");
}

int main(int argc, char *argv[])
{
	start();
	system("pause");
	return 0;
}

客户端 client.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>

#define SIZE 4096
char pipename[32] = "\\\\.\\Pipe\\pipe_server";
HANDLE p_pipe = NULL;

int main(int argc, char *argv[])
{
	p_pipe = CreateFileA(pipename,                   //管道名称
		GENERIC_WRITE | GENERIC_READ,		 //读写
		0,					 //共享属性  0是共享 1是独占                                          
		NULL,					 //默认安全属性
		OPEN_EXISTING,                           //打开已经存在
		FILE_ATTRIBUTE_NORMAL,
		NULL);

	if (p_pipe == INVALID_HANDLE_VALUE)
	{
		printf("打开管道失败!");
		return 0;
	}

	//创建两个随机数
	time_t ts;
	unsigned int num = time(&ts);
	srand(num);
	int numA = rand() % 1000;
	int numB = rand() % 1000;

	char msg[128] = { 0 };
	sprintf(msg, "%d %d", numA, numB);

	//写入
	int nwrite;
	WriteFile(p_pipe, msg, strlen(msg) + 1, &nwrite, NULL);

	//将字符串设置为0
	memset(msg, 0, sizeof(msg));

	//读取
	int nread;
	ReadFile(p_pipe, msg, sizeof(msg), &nread, NULL);
	int result;
	sscanf(msg, "%d", &result);
	printf("%d+%d=%d\n", numA, numB, result);

	system("pause");
	return 0;
}

实现效果
在这里插入图片描述
pipe管道效果

转载自:https://www.qiufengblog.com/articles/pipe2.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值