L o a d i n g . . .
主打一个C++
文章详情

C++编程Windows进程实时通讯(命名管道)

Posted on 2024-12-04 08:23:07 by 主打一个C++

有人问多进程之间怎么实时通讯?

方案之一:使用命名管道(Named Pipe)实现进程间通信,并且可以实时获取新的通信消息

效果:

image.png

上代码:

主端:负责接受副端连接和读取副端发送的数据

// 主为服务端
#include <windows.h>
#include <iostream>

int main() {
    // 创建命名管道
    HANDLE hPipe = CreateNamedPipe(
        L"\\\\.\\pipe\\ProcPipe",  // 管道名称
        PIPE_ACCESS_INBOUND,     // 只读访问
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, // 消息管道
        1,                        // 仅一个实例
        128,                      // 输出缓冲区大小
        128,                      // 输入缓冲区大小
        0,                        // 默认超时
        NULL                      // 默认安全性
    );

    if (hPipe == INVALID_HANDLE_VALUE) {
        std::cerr << "创建管道失败!" << std::endl;
        return 1;
    }

    std::cout << "等待副端连接..." << std::endl;

    // 等待客户端连接
    if (ConnectNamedPipe(hPipe, NULL) != FALSE) {
        char buffer[128];
        DWORD bytesRead;
        printf("副端已连接!\n");
        do
        {
            // 读取消息
            if (ReadFile(hPipe, buffer, sizeof(buffer), &bytesRead, NULL)) {
                std::cout << "接收到副端消息: " << buffer << std::endl;
            }
            else {
                std::cerr << "读取失败!" << std::endl;
                break;
            }
        } while (true);

    }

    CloseHandle(hPipe);
    return 0;
}

副端:连接主端并实时发送的数据

// 副为客户端,负责向主进程发送消息
#include <windows.h>
#include <iostream>
#include <string>
int main() {
    // 创建或打开命名管道
    HANDLE hPipe = CreateFile(
        L"\\\\.\\pipe\\ProcPipe",   // 管道名称
        GENERIC_WRITE,            // 写入权限
        0,                        // 不能共享
        NULL,                     // 默认安全性
        OPEN_EXISTING,           // 打开现有管道
        0,                        // 默认属性
        NULL                      // 无模板文件
    );

    if (hPipe == INVALID_HANDLE_VALUE) {
        std::cerr << "打开管道失败!" << std::endl;
        return 1;
    }
    std::string message = "";
    do
    {
        printf("[副端]输入要发送的消息,exit退出:");
        std::getline(std::cin, message);
        if (message == "exit") {
            break;
        }
        DWORD bytesWritten;
        WriteFile(hPipe, message.c_str(), message.length() + 1, &bytesWritten, NULL);
    } while (true);

    CloseHandle(hPipe);

    return 0;
}

扩展:重点参数详解

  1. PIPE_ACCESS_INBOUND (值为 0x00000001):表示命名管道只能用于接收数据,即客户端可以向服务器发送数据,但服务器不能向客户端发送数据。
  2. PIPE_ACCESS_OUTBOUND (值为 0x00000002):表示命名管道只能用于发送数据,即服务器可以向客户端发送数据,但客户端不能向服务器发送数据。
  3. PIPE_ACCESS_DUPLEX (值为 0x00000003):表示命名管道可以同时用于发送和接收数据,即客户端和服务器都可以相互发送和接收数据。

双向交互修改两端的模式参数即可。

//主端回复消息伪代码:

            //发送消息
            std::string sendMsg = "Hello, 副端!";
            if (WriteFile(hPipe, sendMsg.c_str(), sendMsg.length(), &bytesRead, NULL)) {
                std::cout << "发送消息成功!" << std::endl;
            }
            else {
                std::cerr << "发送失败!" << std::endl;
                break;
            }

//副端读取主端回复

        // 读取主进程返回的消息
        char buffer[1024];
        DWORD bytesRead;
        ReadFile(hPipe, buffer, 1024, &bytesRead, NULL);
        std::cout << "[副端]收到主进程的消息:" << buffer << std::endl;


*转载请注明出处:原文链接:https://cpp.vin/page/101.html

作者近期文章
  • 随手笔记
  • 主打一个C++   2025-01-11 20:02:01
  • 都2000000025年了。还有不能随意访问guthub的,仔细看。在国内其实是可以正常访问的,gfw并没屏蔽。这里给出其中一个简单直接的方法稳定访问。1. 随便百度一个”dn
提示
×
确定
数据库执行: 8次 总耗时: 0.01s
页面加载耗时: 



wechat +447752296473
wechat cpp-blog