当前位置:首页 > C++ > 正文

C++套接字IPC详解(手把手教你实现本地进程间通信)

在现代操作系统中,C++套接字编程是实现IPC通信(Inter-Process Communication,进程间通信)的重要手段之一。尤其在Linux/Unix系统中,使用本地套接字(也称Unix Domain Socket)可以高效、安全地在同一台机器上的不同进程之间交换数据。本教程将从零开始,带你一步步掌握如何用C++编写基于套接字的C++进程间通信程序。

什么是本地套接字?

与网络套接字(如TCP/IP)不同,本地套接字不经过网络协议栈,而是直接通过文件系统路径进行通信,因此速度更快、开销更小。它常用于同一主机内两个进程之间的数据交换,比如Web服务器与其日志服务、数据库客户端与守护进程等。

C++套接字IPC详解(手把手教你实现本地进程间通信) C++套接字编程 IPC通信 C++进程间通信 本地套接字教程 第1张

准备工作

你需要一个支持POSIX标准的系统(如Linux或macOS),以及g++编译器。Windows用户可使用WSL(Windows Subsystem for Linux)。

服务端代码(server.cpp)

服务端负责监听连接并接收消息:

#include <iostream>#include <sys/socket.h>#include <sys/un.h>#include <unistd.h>#include <string.h>#include <cstdlib>#define SOCKET_PATH "/tmp/my_socket"int main() {    int server_fd, client_fd;    struct sockaddr_un addr;    char buffer[1024] = {0};    // 创建套接字    if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {        perror("socket failed");        exit(EXIT_FAILURE);    }    // 配置地址结构    memset(&addr, 0, sizeof(addr));    addr.sun_family = AF_UNIX;    strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);    // 删除已有socket文件(避免bind失败)    unlink(SOCKET_PATH);    // 绑定地址    if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {        perror("bind failed");        close(server_fd);        exit(EXIT_FAILURE);    }    // 监听连接    if (listen(server_fd, 5) == -1) {        perror("listen failed");        close(server_fd);        exit(EXIT_FAILURE);    }    std::cout << "Server is listening on " << SOCKET_PATH << std::endl;    // 接受客户端连接    if ((client_fd = accept(server_fd, nullptr, nullptr)) == -1) {        perror("accept failed");        close(server_fd);        exit(EXIT_FAILURE);    }    // 接收数据    int bytes_read = read(client_fd, buffer, sizeof(buffer) - 1);    if (bytes_read > 0) {        buffer[bytes_read] = '\0';        std::cout << "Received: " << buffer << std::endl;    }    // 回复客户端    const char* reply = "Message received!";    write(client_fd, reply, strlen(reply));    // 清理资源    close(client_fd);    close(server_fd);    unlink(SOCKET_PATH); // 删除socket文件    return 0;}

客户端代码(client.cpp)

客户端主动连接服务端并发送消息:

#include <iostream>#include <sys/socket.h>#include <sys/un.h>#include <unistd.h>#include <string.h>#include <cstdlib>#define SOCKET_PATH "/tmp/my_socket"int main() {    int sock_fd;    struct sockaddr_un addr;    char buffer[1024] = {0};    // 创建套接字    if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {        perror("socket failed");        exit(EXIT_FAILURE);    }    // 配置地址结构    memset(&addr, 0, sizeof(addr));    addr.sun_family = AF_UNIX;    strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);    // 连接服务端    if (connect(sock_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {        perror("connect failed");        close(sock_fd);        exit(EXIT_FAILURE);    }    // 发送消息    const char* message = "Hello from client!";    write(sock_fd, message, strlen(message));    // 接收回复    int bytes_read = read(sock_fd, buffer, sizeof(buffer) - 1);    if (bytes_read > 0) {        buffer[bytes_read] = '\0';        std::cout << "Server replied: " << buffer << std::endl;    }    // 关闭连接    close(sock_fd);    return 0;}

编译与运行

打开终端,执行以下命令:

# 编译服务端g++ -o server server.cpp# 编译客户端g++ -o client client.cpp# 先运行服务端(会阻塞等待连接)./server# 在另一个终端窗口运行客户端./client

你将看到服务端输出收到的消息,客户端收到服务端的确认回复。这就是一个完整的本地套接字教程实践!

注意事项

  • 每次运行前确保没有残留的 /tmp/my_socket 文件,否则bind会失败。
  • 本地套接字仅限于同一主机,不能跨网络使用。
  • 权限问题:确保进程有权限创建和访问socket文件。
  • 错误处理很重要!实际项目中应更完善地处理各种异常情况。

总结

通过本教程,你已经掌握了使用C++套接字编程实现IPC通信的基本方法。本地套接字是C++进程间通信的高效方案之一,适用于许多需要高性能本地通信的场景。希望这个本地套接字教程能为你打下坚实基础,助你在系统编程之路上更进一步!