news 2026/2/20 2:13:41

本机进程间通信的一种方式:UDS入门篇一

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
本机进程间通信的一种方式:UDS入门篇一

✅ 一、UDS 是什么?

UDS= Unix Domain Socket(也叫 IPC Socket,也叫域内通信)它是 Linux/Unix 系统中一种进程间通信(IPC:Inter-Process Communication)机制,用于同一台机器上的两个进程之间通信

📌 和 TCP/IP Socket 不同:

  • TCP/IP 用于跨网络通信(哪怕本机回环127.0.0.1也要走网络协议栈)
  • UDS只在本机内核内存缓冲区中进行传输不经过网络协议栈(所以wireshark无法抓到包),因此更快、更轻量、更安全。

✅ 二、UDS 是一种框架还是内核实现的代码?

UDS 是Linux 内核实现的,用户直接调系统接口即可。

  • socket API 的一部分,属于 POSIX 标准。
  • 内核在AF_UNIX地址族(Address Family)下实现了完整的通信逻辑。
  • 用户程序通过标准的系统调用(如socket(),bind(),connect(),send(),recv()等)来使用它,就像用 TCP 一样,只是地址类型不同。

✅ 三、UDS 怎么用?

1. 创建 UDS句柄

int sockfd = socket(AF_UNIX, SOCK_STREAM, 0); // 或 SOCK_DGRAM
  • AF_UNIX表示使用 Unix Domain Socket
  • SOCK_STREAM→ 类似 TCP(可靠、有序)
  • SOCK_DGRAM→ 类似 UDP(无连接、消息边界)
  • 核心真相:UDS的"TCP/UDP"是内核IPC

  • 1.网络栈 vs 内核IPC通道的底层原理:

    • 网络通信:
      应用层 → TCP/UDP协议栈 → IP层 → 网卡驱动 → 物理网卡
      ^^^^^^^^^^^^^^^^^^
      真正的TCP/UDP协议处理

      UDS通信:
      应用层 → 内核IPC模块 → 内核缓冲区

      ^^^^^^^^^^^^^^
      只是借用了TCP/UDP的API模型

  • 关键点:UDS的SOCK_STREAM/SOCK_DGRAM只是接口语义不是协议实现

  • 扩展知识:int socket(int domain, int type, int protocol);函数原型:
    • 1.domain(通信的协议族/地址族)常用的domain有:
      • 常量

        说明

        AF_INET

        AF_INET

        IPv4 网络协议(最常用)

        AF_INET6

        AF_INET6

        IPv6 网络协议

        AF_UNIX

        AF_UNIX/AF_LOCAL

        本地进程间通信

        AF_PACKET

        AF_PACKET

        底层数据包接口

    • 2. type(套接字类型):
      • 常量

        说明

        1

        SOCK_STREAM

        面向连接的可靠字节流(TCP)

        2

        SOCK_DGRAM

        无连接不可靠数据报(UDP)

        3

        SOCK_RAW

        原始套接字(直接访问网络层)

2. 绑定地址(服务端)

UDS 的“地址”文件通常是一个文件系统路径(如/tmp/mysocket):

struct sockaddr_un addr; memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, "/tmp/mysocket"); bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));

⚠️ 注意:UDS地址路径本质:Unix Domain Socket(UDS)文件只是一个“命名标识符”(name endpoint),并不用于存储通信数据。它的作用类似于 TCP 中的 “IP 地址 + 端口号”—— 只是用来标识一个通信端点,而不是数据容器,实际数据不写入磁盘

例如:ls -l/tmp/mysocket

srwxrwxr-x 1 XX XX012月 17 16:18 /tmp/mysocket

备注:

  • uds地址文件:由调用bind()的进程创建(通常是服务端);
    • bind()成功返回,该 socket 文件就出现在文件系统中。
    • 如果路径已存在同名文件(比如上次崩溃没清理),bind()会失败(返回-1,errno 为EADDRINUSE)。所以通常服务端会在bind()前先unlink()。
    • 注意:客户端不需要也不应该创建这个文件。客户端只通过路径去connect()
    • 服务端进程退出自动销毁。

3. 连接(客户端)

客户端也创建AF_UNIXsocket,connect()到与服务端同一个uds路径(如/tmp/mysocket):

connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));

4. 通信

之后就可以用read()/write()send()/recv()像普通 socket 一样收发数据。

5. 清理

通信结束后,服务端应unlink("/tmp/mysocket")删除 socket 文件,避免残留。

6.完整的 C 语言 Unix Domain Socket(UDS)示例:

  • 服务端(server):监听/tmp/example.sock,接收客户端消息并回显。
  • 客户端(client):连接到该 socket,发送一条消息并打印回复。
  • 服务端代码:server.c
  • // server.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> #include <errno.h> #define SOCKET_PATH "/tmp/example.sock" #define BUFFER_SIZE 256 int main() { int server_fd, client_fd; struct sockaddr_un addr; char buffer[BUFFER_SIZE]; // 1. 创建 UDS socket server_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (server_fd == -1) { perror("socket"); exit(EXIT_FAILURE); } // 2. 准备地址结构 memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1); // 3. 删除可能存在的旧 socket 文件 unlink(SOCKET_PATH); // 4. 绑定地址 if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { perror("bind"); close(server_fd); exit(EXIT_FAILURE); } // 5. 监听连接 if (listen(server_fd, 5) == -1) { perror("listen"); close(server_fd); unlink(SOCKET_PATH); exit(EXIT_FAILURE); } printf("Server listening on %s\n", SOCKET_PATH); // 6. 接受客户端连接 client_fd = accept(server_fd, NULL, NULL); if (client_fd == -1) { perror("accept"); } else { // 7. 读取客户端数据 ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE - 1); if (bytes_read > 0) { buffer[bytes_read] = '\0'; printf("Received: %s", buffer); // 8. 回显给客户端 write(client_fd, buffer, bytes_read); } close(client_fd); } // 9. 清理 close(server_fd); unlink(SOCKET_PATH); // 删除 socket 文件 printf("Server shutdown.\n"); return 0; }
  • 客户端代码:client.c
  • // client.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> #define SOCKET_PATH "/tmp/example.sock" #define MESSAGE "Hello from client!\n" int main() { int sock_fd; struct sockaddr_un addr; char buffer[256]; // 1. 创建 UDS socket sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (sock_fd == -1) { perror("socket"); exit(EXIT_FAILURE); } // 2. 设置服务器地址 memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1); // 3. 连接到服务端 if (connect(sock_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { perror("connect"); close(sock_fd); exit(EXIT_FAILURE); } // 4. 发送消息 if (write(sock_fd, MESSAGE, strlen(MESSAGE)) != (ssize_t)strlen(MESSAGE)) { perror("write"); } else { printf("Sent: %s", MESSAGE); // 5. 接收回复 ssize_t bytes_read = read(sock_fd, buffer, sizeof(buffer) - 1); if (bytes_read > 0) { buffer[bytes_read] = '\0'; printf("Received echo: %s", buffer); } } close(sock_fd); return 0; }
  • 运行效果:
    • 先启动服务端(它会阻塞等待连接)./server
    • 再在另一个终端运行客户端./client
  • 预期输出:
    • 服务端打印:
      • Server listening on /tmp/example.sock
        Received: Hello from client!
        Server shutdown.
    • 客户端打印:
      • Sent: Hello from client!
        Received echo: Hello from client!
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/17 10:02:36

CST设计:可重构超表面宽带窄带可切换吸收与多波束技术

CST设计 可重构超表面 宽带窄带可切换吸收与多波束超表面玩得溜&#xff0c;参数设计能愁秃头。今天咱们来点实战干货&#xff0c;聊聊用CST折腾可重构超表面的骚操作——既能当宽带吸波毯子&#xff0c;又能秒变窄带信号捕捉器&#xff0c;顺手再甩几个多波束出来。先上硬菜&…

作者头像 李华
网站建设 2026/2/17 20:37:01

ai智能搜索文献:高效精准的学术资源检索新工具与应用研究

传统的文献搜索&#xff0c;是我们去适应机器的逻辑&#xff1a;拆解关键词、使用布尔运算符&#xff08;AND, OR, NOT&#xff09;。而新一代的AI学术工具&#xff0c;正在让机器来适应人类的思维&#xff1a;它们能理解模糊的问题&#xff0c;能联想相关的概念&#xff0c;甚…

作者头像 李华
网站建设 2026/2/7 4:40:38

英文文献的高效检索与阅读策略研究

传统的文献搜索&#xff0c;是我们去适应机器的逻辑&#xff1a;拆解关键词、使用布尔运算符&#xff08;AND, OR, NOT&#xff09;。而新一代的AI学术工具&#xff0c;正在让机器来适应人类的思维&#xff1a;它们能理解模糊的问题&#xff0c;能联想相关的概念&#xff0c;甚…

作者头像 李华
网站建设 2026/2/20 0:26:48

打造专属问答社区,开源系统助力内容创业新风口

温馨提示&#xff1a;文末有资源获取方式在当前互联网环境中&#xff0c;内容为王依然是铁律&#xff0c;而问答型平台以其高度的用户互动性和内容价值&#xff0c;始终占据着重要地位。你是否也曾梦想拥有一个类似知乎、百度知道的网站&#xff0c;用于知识分享、品牌互动或内…

作者头像 李华