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

C语言套接字IPC(基于Unix域套接字的进程间通信实战教程)

在Linux/Unix系统中,C语言套接字IPC(Inter-Process Communication,进程间通信)是一种高效、灵活的通信机制。尤其当多个进程运行在同一台机器上时,使用Unix域套接字(Unix Domain Socket)比网络套接字更高效、更安全。本教程将手把手教你如何用C语言实现基于Unix域套接字的进程间通信,即使是编程小白也能轻松上手!

什么是Unix域套接字?

Unix域套接字(也称本地套接字)是一种仅用于同一主机内进程通信的IPC机制。它不经过网络协议栈,因此比TCP/IP套接字更快、开销更小。它支持流式(SOCK_STREAM)和数据报(SOCK_DGRAM)两种模式,常用于守护进程与客户端之间的通信。

C语言套接字IPC(基于Unix域套接字的进程间通信实战教程) C语言套接字IPC 进程间通信 Unix域套接字 C语言网络编程 第1张

准备工作

你需要:

  • 一台安装了Linux或macOS的电脑(Windows需WSL)
  • GCC编译器(可通过 gcc --version 检查)
  • 基础的C语言知识

服务端代码实现

服务端负责监听并接收客户端发来的消息。以下是完整的C语言服务端代码:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <sys/un.h>#define SOCK_PATH "/tmp/my_socket"#define BUFFER_SIZE 1024int main() {    int server_fd, client_fd;    struct sockaddr_un server_addr, client_addr;    socklen_t addr_size;    char buffer[BUFFER_SIZE];    // 创建Unix域套接字    server_fd = socket(AF_UNIX, SOCK_STREAM, 0);    if (server_fd == -1) {        perror("socket failed");        exit(EXIT_FAILURE);    }    // 配置服务器地址    memset(&server_addr, 0, sizeof(server_addr));    server_addr.sun_family = AF_UNIX;    strncpy(server_addr.sun_path, SOCK_PATH, sizeof(server_addr.sun_path) - 1);    // 绑定套接字    unlink(SOCK_PATH); // 删除已存在的socket文件    if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_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);    }    printf("[Server] 等待客户端连接...\n");    while (1) {        addr_size = sizeof(client_addr);        client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addr_size);        if (client_fd == -1) {            perror("accept failed");            continue;        }        // 接收客户端消息        ssize_t bytes = read(client_fd, buffer, BUFFER_SIZE - 1);        if (bytes > 0) {            buffer[bytes] = '\0';            printf("[Server] 收到消息: %s\n", buffer);            // 回复客户端            const char* reply = "消息已收到!";            write(client_fd, reply, strlen(reply));        }        close(client_fd);    }    close(server_fd);    unlink(SOCK_PATH);    return 0;}

客户端代码实现

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

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <sys/un.h>#define SOCK_PATH "/tmp/my_socket"#define BUFFER_SIZE 1024int main() {    int client_fd;    struct sockaddr_un server_addr;    char buffer[BUFFER_SIZE];    // 创建套接字    client_fd = socket(AF_UNIX, SOCK_STREAM, 0);    if (client_fd == -1) {        perror("socket failed");        exit(EXIT_FAILURE);    }    // 配置服务器地址    memset(&server_addr, 0, sizeof(server_addr));    server_addr.sun_family = AF_UNIX;    strncpy(server_addr.sun_path, SOCK_PATH, sizeof(server_addr.sun_path) - 1);    // 连接服务器    if (connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {        perror("connect failed");        close(client_fd);        exit(EXIT_FAILURE);    }    // 发送消息    const char* message = "Hello from client!";    write(client_fd, message, strlen(message));    printf("[Client] 已发送: %s\n", message);    // 接收回复    ssize_t bytes = read(client_fd, buffer, BUFFER_SIZE - 1);    if (bytes > 0) {        buffer[bytes] = '\0';        printf("[Client] 收到回复: %s\n", buffer);    }    close(client_fd);    return 0;}

编译与运行

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

# 编译服务端gcc server.c -o server# 编译客户端gcc client.c -o client# 先启动服务端(后台运行)./server &# 再运行客户端./client

你将看到类似如下输出:

[Server] 等待客户端连接...[Client] 已发送: Hello from client![Server] 收到消息: Hello from client![Client] 收到回复: 消息已收到!

关键知识点总结

通过本教程,你掌握了以下C语言网络编程核心概念:

  • 使用 AF_UNIX 创建本地通信套接字
  • 通过 bind()listen()accept() 实现服务端监听
  • 客户端使用 connect() 主动连接
  • 利用 read()write() 进行双向数据交换

这种基于Unix域套接字进程间通信方式非常适合构建本地高性能应用,如数据库连接池、日志收集器、微服务本地代理等场景。

注意事项

  • 每次运行前确保删除旧的socket文件(unlink(SOCK_PATH)
  • 路径长度不能超过 sizeof(sockaddr_un.sun_path)(通常为108字节)
  • 生产环境中应加入错误处理、信号捕获和资源清理逻辑

现在你已经掌握了C语言套接字IPC的基础用法!快动手试试吧,为你的项目添加高效的本地通信能力!