管道通信初级

来源:互联网 发布:netbeans 如何配置php 编辑:程序博客网 时间:2024/06/16 11:43

1. pipe管道通信,其实socket也要依赖于它,可以实现双向通信。还能解决并发。
比共享内存和邮槽都靠谱。
2. 禁止一个程序打开多次,也就是锁定一个程序只能打开一次,限制它的打开次数,用管道就    必须这么做,否则会发生冲突。
3.有线程池也有管道池

4.例子

  • 服务端
复制代码
#include <stdio.h>#include <Windows.h>//管道是存在于操作系统#define SIZE 4096char pipename[128] = "\\\\.\\Pipe\\guandaopipe";    //用这种模式命名等同于设备。HANDLE m_pipe = NULL;    //管道的句柄//创建一个管道void start(){    m_pipe = CreateNamedPipeA(        pipename,    //管道名称        PIPE_ACCESS_DUPLEX,    //管道的读写属性        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,        //消息模式,读模式,等待模式(相当于阻塞模式)PIPE_TYPE_MESSAGE一般情况有两种,用的最多的是消息模式,另一种是二进制模式(BYTE模式)。        PIPE_UNLIMITED_INSTANCES,//同时开启管道的最大个数,最多是255,在服务器上可以开辟更多。        SIZE,    //输出(读)的缓冲区大小        SIZE,    //输出(写)的缓冲区大小        0,    //客户端超时时间        NULL        );        if (m_pipe == NULL)        {            printf("创建失败");            return;        }        //连接这个管道并且判断是否连上。        BOOL isconnect = ConnectNamedPipe(m_pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);        if (isconnect)        {            MessageBoxA(0, "connected OK", "connected OK", 0);        }        else        {            printf("创建失败。");        }}void read(){    char buf[SIZE] = { 0 };        //我们有可能把管道的所有信息都读了,初始化时原则上初始为0。    int last = 0;    if (!ReadFile(m_pipe, buf, SIZE, &last, NULL))    //Readpipe是纯C语言里边,如果是C的管道库,用Readpipe,C语言把所有的设备当成文件来处理,所以用ReadFile,若返回值是0表示读取失败.    {        printf("读取失败");        return;    }    printf("\nread%s", buf);}void write(){    char str[128] = "举头望明月,这就是管道。";        int last = 0;        BOOL res = WriteFile(m_pipe, str, sizeof(str), &last, NULL);        if (!res)        {            printf("写入失败");        }}void test(){    //先尝试能不能打开,打开了,就说明原来存在。如果没有打开就创建一个。    HANDLE mutex = OpenMutexA(MUTEX_ALL_ACCESS, TRUE, "guandaoserver"); //把guandaoserver去掉就是匿名,就不能跨进程了。        if (mutex == NULL)        {//创建            mutex = CreateMutexA(NULL, TRUE, "guandaoserver"); //如果是匿名就不能发挥作用了        }        else        {            MessageBoxA(0, "only one", "only one", 0);            exit(0); //exit(0)表示正常退出,exit(x)都表示异常退出.        }}//mutex是内核所有的进程都能读到,限定程序只能打开一次。void main(){    test();    start();    printf("服务器启动\n");    system("pause");    write();    system("pause");    read();    system("pause");}

 

  • 客户端

#include <stdio.h>#include <Windows.h>#define SIZE 4096char pipename[128] = "\\\\.\\Pipe\\guandaopipe";    //用这种模式命名等同于设备。HANDLE m_pipe = NULL;    //管道的句柄void read(){    char buf[SIZE] = { 0 };        //我们有可能把管道的所有信息都读了,初始化时原则上初始为0。    int last = 0;    if (!ReadFile(m_pipe, buf, SIZE, &last, NULL))    //Readpipe是纯C语言里边,如果是C的管道库,用Readpipe,C语言把所有的设备当成文件来处理,所以用ReadFile,若返回值是0表示读取失败.    {        printf("读取失败");        return;    }    printf("\nread%s", buf);}void write(){    char str[128] = "又丑又傻多看书。";    int last = 0;    BOOL res = WriteFile(m_pipe, str, sizeof(str), &last, NULL);    if (!res)    {        printf("写入失败");    }}void main(){    //NMPWAIT_WAIT_FOREVER 常用到无限等待,表示如果没有管道就一直卡着    if (!WaitNamedPipeA(pipename, NMPWAIT_USE_DEFAULT_WAIT))        //NMPWAIT_USE_DEFAULT_WAIT表示一般等待,只等一下    {        MessageBoxA(0, "connected NO", "connected NO", 0);        return;    }    m_pipe = CreateFileA(pipename, //名称        GENERIC_WRITE | GENERIC_READ, //既能读又能写,是通过位运算符实现的。        1, //表示是否共享        NULL, //默认安全属性        OPEN_EXISTING, //打开已经存在的        FILE_ATTRIBUTE_NORMAL,//这两个表示两个默认的属性        NULL        );        system("pause");    read();    system("pause");    write();    system("pause");}
0 0
原创粉丝点击