news 2026/4/16 14:26:46

本机进程间通信的一种方式: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/4/16 10:49:23

PM2 WebUI终极指南:5分钟搭建免费Node.js应用管理平台

PM2 WebUI终极指南&#xff1a;5分钟搭建免费Node.js应用管理平台 【免费下载链接】pm2-webui PM2 WebUI. Opensource Alternative to PM2 Plus. Minimalistic App Manager and Log Viewer 项目地址: https://gitcode.com/gh_mirrors/pm/pm2-webui 还在为复杂的Node.js应…

作者头像 李华
网站建设 2026/4/16 12:09:26

同步整流PSFB:一场电源转换的效率革命

同步整流PSFB移相全桥变换器电压电流双闭环控制。 原边四个mos管均可实现zvs软开关。 副边采用mos替换传统二极管&#xff0c;降低其导通损耗。 0.025s时刻由满载工况切为半载工况&#xff0c;闭环稳定效果良好&#xff0c;如展示图所示。 运行环境为matlab/simulink在电源管理…

作者头像 李华
网站建设 2026/4/16 15:32:42

复现 Comsol 污染物地下运移模型:以苯污染为例

【comsol污染物地下运移模型】参考某中文期刊低渗透介质中轻非水相流体迁移转化规律&#xff0c;考虑对流&#xff0c;弥散&#xff0c;颗粒吸附等影响&#xff0c;以苯为污染源为例&#xff1b; 【复现效果】:基本复现&#xff0c;文中些许部分内容未详细给出&#xff0c;模型…

作者头像 李华
网站建设 2026/4/16 13:52:01

低轨卫星物联网VS低轨卫星互联网,核心差异一文看懂!

12月6日至12日&#xff0c;中国星网的低轨14组、15组、16组卫星相继入轨&#xff0c;再次彰显出中国星网低轨卫星组网“发射密集、进程加速”的强劲态势。 自今年4月起&#xff0c;中国星网便保持着每月至少发射一组卫星的稳定节奏&#xff0c;甚至出现过一月四发的壮举&#…

作者头像 李华
网站建设 2026/4/16 12:02:08

私有化部署新选择,这款高性能表单系统源码,带完整的搭建部署教程

温馨提示&#xff1a;文末有资源获取方式 在数据安全和定制化需求日益增长的今天&#xff0c;许多企业和开发者正在寻求能够自主掌控、灵活定制的业务工具。我们为您带来一款支持私有化部署的强大表单系统&#xff0c;它不仅功能全面&#xff0c;更以出色的性能、稳定的底层和无…

作者头像 李华