使用管道实现一对多进程通信
前言
在使用管道进行进程间通信,这里实现客户端发送两个参数,服务端接收两个参数,将处理过的结果返回.服务端 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;
}
实现效果

秋风
2016-07-24