C++ 两个进程/exe之前的通讯方式

1. 命名管道(Named Pipes)

1.1. 概述

命名管道是一种用于进程间通信的机制,允许数据在进程之间以管道的形式进行传输。命名管道可以在同一台计算机上或通过网络连接的计算机之间使用。

1.2. 特点

双向通信:命名管道支持同时发送和接收数据。
异步和同步操作:支持客户端和服务器的非阻塞和阻塞操作。
网络支持:可用于不同计算机间的通信。
安全性:可以设置访问权限,确保数据的安全性。

1.3. 实现方式

1.3.1. 服务器端示例
#include <windows.h>
#include <iostream>

int main() {
    // 创建命名管道
    HANDLE hPipe = CreateNamedPipe(
        L"\\\\.\\pipe\\MyNamedPipe",     // 命名管道名称
        PIPE_ACCESS_DUPLEX,              // 双向访问
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, // 消息管道
        PIPE_UNLIMITED_INSTANCES,        // 实例数量
        512, 512, 0, NULL);              // 缓冲区大小

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

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

    // 等待客户端连接
    if (ConnectNamedPipe(hPipe, NULL) != FALSE) {
        std::cout << "客户端已连接。" << std::endl;

        char buffer[128];
        DWORD bytesRead;
        // 从管道读取数据
        if (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &bytesRead, NULL)) {
            buffer[bytesRead] = '\0';
            std::cout << "从客户端收到消息: " << buffer << std::endl;

            // 向客户端发送回应
            const char* response = "Hello from server!";
            DWORD bytesWritten;
            WriteFile(hPipe, response, strlen(response), &bytesWritten, NULL);
        }
    }

    CloseHandle(hPipe);
    return 0;
}
1.3.2. 客户端示例
#include <windows.h>
#include <iostream>

int main() {
    // 打开命名管道
    HANDLE hPipe = CreateFile(
        L"\\\\.\\pipe\\MyNamedPipe",     // 与服务器端管道名称一致
        GENERIC_READ | GENERIC_WRITE,    // 读写权限
        0, NULL, OPEN_EXISTING, 0, NULL);

    if (hPipe == INVALID_HANDLE_VALUE) {
        std::cerr << "连接到管道失败" << std::endl;
        return 1;
    }

    // 向服务器发送数据
    const char* message = "Hello from client!";
    DWORD bytesWritten;
    WriteFile(hPipe, message, strlen(message), &bytesWritten, NULL);

    char buffer[128];
    DWORD bytesRead;
    // 从服务器读取回应
    if (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &bytesRead, NULL)) {
        buffer[bytesRead] = '\0';
        std::cout << "从服务器收到消息: " << buffer << std::endl;
    }

    CloseHandle(hPipe);
    return 0;
}

1.4. 使用场景

适合:需要在不同进程之间传输消息或数据,特别是在客户端和服务器之间。
优点:易于实现、支持多客户端连接、提供一定的安全性。

2. 套接字(Sockets)

2.1. 概述

套接字是网络通信的基本概念,可以在同一台计算机上或跨网络的进程之间进行通信。可以使用 TCP 和 UDP 协议。

2.2. 特点

灵活性:可以支持不同的协议(TCP、UDP)。
跨平台:在不同操作系统之间的兼容性好。
可扩展性:适合构建分布式应用程序。

2.3. 实现方式

2.3.1. 服务器端(TCP 套接字)
#include <iostream>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

int main() {
    // 初始化 Winsock
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    // 创建套接字
    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(8080);

    // 绑定套接字
    bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));

    // 监听连接
    listen(serverSocket, SOMAXCONN);

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

    sockaddr_in clientAddr;
    int clientAddrSize = sizeof(clientAddr);
    SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrSize);

    if (clientSocket != INVALID_SOCKET) {
        std::cout << "客户端已连接。" << std::endl;

        char buffer[128];
        int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
        if (bytesReceived > 0) {
            buffer[bytesReceived] = '\0';
            std::cout << "收到客户端消息: " << buffer << std::endl;

            // 发送回应
            const char* response = "Hello from server!";
            send(clientSocket, response, strlen(response), 0);
        }
        closesocket(clientSocket);
    }

    closesocket(serverSocket);
    WSACleanup();
    return 0;
}
2.3.2. 客户端(TCP 套接字)
#include <iostream>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

int main() {
    // 初始化 Winsock
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    // 创建套接字
    SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器 IP 地址
    serverAddr.sin_port = htons(8080);

    // 连接到服务器
    connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));

    // 发送数据
    const char* message = "Hello from client!";
    send(clientSocket, message, strlen(message), 0);

    char buffer[128];
    int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
    if (bytesReceived > 0) {
        buffer[bytesReceived] = '\0';
        std::cout << "收到服务器消息: " << buffer << std::endl;
    }

    closesocket(clientSocket);
    WSACleanup();
    return 0;
}

2.4. 使用场景

适合:需要在分布式环境中进行通信的应用,如网络服务、聊天程序等。
优点:支持多种协议,能够处理大量并发连接。

3. 共享内存(Shared Memory)

3.1. 概述

共享内存是一种高效的进程间通信方式,通过允许多个进程访问同一块内存区域来实现快速数据交换。

3.2. 特点

高性能:避免了数据复制,速度快。
实时性:适合需要快速、实时数据交换的场景。
同步复杂性:需要额外的机制来防止数据冲突。

3.3. 实现方式

3.3.1. 服务器端(共享内存)
#include <windows.h>
#include <iostream>

int main() {
    // 创建共享内存
    HANDLE hMapFile = CreateFileMapping(
        INVALID_HANDLE_VALUE,   // 使用分页文件
        NULL,                   // 默认安全属性
        PAGE_READWRITE,         // 可读写
        0,                      // 高位文件大小
        256,                    // 低位文件大小
        L"MySharedMemory");      // 共享内存名称

    if (hMapFile == NULL) {
        std::cerr << "创建共享内存失败" << std::endl;
        return 1;
    }

    // 映射共享内存
    LPCTSTR pBuf = (LPTSTR)MapViewOfFile(
        hMapFile,                // 共享内存句柄
        FILE_MAP_ALL_ACCESS,     // 读写访问
        0,                       // 高位偏移
        0,                       // 低位偏移
        256);                    // 映射大小

    if (pBuf == NULL) {
        std::cerr << "映射共享内存失败" << std::endl;
        CloseHandle(hMapFile);
        return 1;
    }

    // 写入数据到共享内存
    CopyMemory((PVOID)pBuf, L"Hello from server!", sizeof(L"Hello from server!"));

    std::cout << "数据写入共享内存。" << std::endl;

    // 等待用户输入以保持共享内存
    std::cin.get();

    UnmapViewOfFile(pBuf);
    CloseHandle(hMapFile);
    return 0;
}
3.3.2. 客户端(共享内存)
#include <windows.h>
#include <iostream>

int main() {
    // 打开共享内存
    HANDLE hMapFile = OpenFileMapping(
        FILE_MAP_ALL_ACCESS,    // 读写访问
        FALSE,                  // 不继承句柄
        L"MySharedMemory");      // 共享内存名称

    if (hMapFile == NULL) {
        std::cerr << "打开共享内存失败" << std::endl;
        return 1;
    }

    // 映射共享内存
    LPCTSTR pBuf = (LPTSTR)MapViewOfFile(
        hMapFile,               // 共享内存句柄
        FILE_MAP_ALL_ACCESS,    // 读写访问
        0,                      // 高位偏移
        0,                      // 低位偏移
        256);                   // 映射大小

    if (pBuf == NULL) {
        std::cerr << "映射共享内存失败" << std::endl;
        CloseHandle(hMapFile);
        return 1;
    }

    // 读取共享内存中的数据
    std::wcout << L"从共享内存读取数据: " << pBuf << std::endl;

    UnmapViewOfFile(pBuf);
    CloseHandle(hMapFile);
    return 0;
}

3.4. 使用场景

适合:高性能、实时数据交换需求,如视频流处理、实时数据分析。
优点:高效,适合大规模数据传输。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑非不退

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值