• 管道通信初级


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

    4.例子

    • 服务端
    #include <stdio.h>
    #include <Windows.h>
    
    //管道是存在于操作系统
    #define SIZE 4096
    char 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("
    read%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("服务器启动
    ");
        system("pause");
        write();
        system("pause");
        read();
        system("pause");
    }
    • 客户端
    #include <stdio.h>
    #include <Windows.h>
    
    #define SIZE 4096
    char 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("
    read%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, //表示是否共享,1表示独有,0表示共有
            NULL, //默认安全属性
            OPEN_EXISTING, //打开已经存在的
            FILE_ATTRIBUTE_NORMAL,//这两个表示两个默认的属性
            NULL
            );
    
        
    
        system("pause");
        read();
        system("pause");
        write();
        system("pause");
    
    }
  • 相关阅读:
    Eigen SSE兼容,内存分配,和std容器的兼容理解
    Qt 进程守护程序(windows、linux)
    c++ vector 大数加法
    C#整合ActiveMQ与SpringBoot整合ActiveMQ数据间交互
    vue.js3:使用clipboard.js实现复制到剪贴板(vue@3.2.37 / clipboard@2.0.11)
    vue.js3: html的十六进制和rgb颜色互相转换(vue@3.2.37)
    spring boot: 用pinyin4j把中文转换为汉语拼音(spring boot v2.5.4)
    vue.js3: base64编码/解码(vue@3.2.37)
    vue.js3:封装一个选择国家或地区的component(vue@3.2.37)
    vue.js3: 使用elementplus的icon图标(vue@3.2.37 / @elementplus/iconsvue@2.0.6)
  • 原文地址:https://www.cnblogs.com/sjxbg/p/5946323.html
Copyright © 2020-2023  润新知