使用管道进行进程间通信-秋风
前言
前面使用邮槽进行实现了进程间的通信,只不过邮槽通信是一个发送,一个接送.而且邮槽不是可靠的.这里使用管道实现进程通信的收发.服务端 server.c
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#define SIZE 4096
//管道名称 格式 以\\\\.\\Pipe\\管道名
char pipename[32] = "\\\\.\\Pipe\\pipe_server";
//管道句柄
HANDLE p_pipe = NULL;
void pipe_start()
{
p_pipe = CreateNamedPipeA(
pipename, //管道名称
PIPE_ACCESS_DUPLEX, //管道读写属性
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, //消息模式,读模式,等待模式
PIPE_UNLIMITED_INSTANCES, //最大个数
SIZE, //输出缓冲区大小
SIZE, //输入缓冲区大小
0, //超时,无限等待
NULL
);
if (p_pipe == NULL)
{
printf("创建管道失败!\n");
}
//是否连接上管道
BOOL isConnect = ConnectNamedPipe(p_pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
if (isConnect)
{
printf("连接完成!\n");
}
else
{
printf("管道连接失败!\n");
}
}
//读取
void read()
{
char buf[SIZE] = { 0 };
int last = 0;
//ReadFile
//第一个参数句柄
//第二个字符指针
//第三个字符大小
//第四个实际读取的字符数量
//第五个异步读取操作使用,这是不使用
if (!ReadFile(p_pipe, buf, SIZE, &last, NULL))
{
printf("读取失败!\n");
}
else
{
buf[last] = '\0';
printf("服务器读取= %s\n", buf);
}
}
//写入
void write()
{
char str[128] = "hello";
int writeCount = 0;
//WriteFile
//第一个参数句柄
//第二个字符指针
//第三个字符大小
//第四个实际写入的字符数量
BOOL result = WriteFile(p_pipe, str, strlen(str) + 1, &writeCount, NULL);
if (!result)
{
printf("写入失败!\n");
return;
}
printf("服务器写入=%s\n", str);
}
//通过互斥体,实现进程唯一
void test()
{
HANDLE mutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, "pipe_server");
if (mutex == NULL)
{
mutex = CreateMutexA(NULL, TRUE, "pipe_server");
}
else
{
MessageBoxA(0, "only one", "only on", 0);
exit(0);
}
}
int main(int argc, char *argv[])
{
test();
pipe_start();
printf("管道启动..\n");
write();
read();
system("pause");
return 0;
}
客户端 client.c
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#define SIZE 4096
//管道名称格式 以\\\\.\\Pipe\\管道名
char pipename[32] = "\\\\.\\Pipe\\pipe_server";
//管道句柄
HANDLE p_pipe = NULL;
//读取
void pipe_read()
{
char buf[SIZE] = { 0 };
int readCount = 0;
if (!ReadFile(p_pipe, buf, SIZE, &readCount, NULL))
{
printf("读取失败!\n");
return;
}
else
{
buf[readCount] = '\0';
printf("客户端读取= %s\n", buf);
}
}
//写入
void pipe_write()
{
char str[128] = "word";
int writeCount = 0;
BOOL result = WriteFile(p_pipe, str, strlen(str) + 1, &writeCount,NULL);
if (!result)
{
printf("写入失败!\n");
return;
}
printf("客户端写入=%s\n", str);
}
int main()
{
if (!WaitNamedPipeA(pipename, NMPWAIT_USE_DEFAULT_WAIT))
{
printf("没有连接上!\n");
return 0;
}
p_pipe = CreateFileA(pipename, //管道名称
GENERIC_READ | GENERIC_WRITE, //读写
1, //共享属性 0是共享 1是独占
NULL, //默认安全属性
OPEN_EXISTING, //打开已经存在
FILE_ATTRIBUTE_NORMAL,
NULL);
pipe_read();
pipe_write();
system("pause");
return 0;
}
注意事项
- 先生成服务端server.c,在服务端test方法中,用互斥体来校验是否已经在进程中存在.
秋风
2016-07-24