Unix Socket(通常称为 Unix Domain Socket,UDS )是一种 仅在同一台主机内部使用的进程间通信(IPC, Inter-Process Communication)机制。它利用文件系统路径作为通信端点,通过内核在本机进程之间高效地传递数据。
一、Unix Socket 的核心概念
定义
Unix Socket 是一种基于 socket 接口、但不经过网络协议栈(如 TCP/IP)的本地通信方式,通信双方必须运行在同一台操作系统上。
本质
-
属于 socket 家族之一(
AF_UNIX或AF_LOCAL) -
通信端点不是 IP + 端口,而是 文件系统中的一个路径
-
数据在内核态直接拷贝,性能优于 TCP
二、Unix Socket 与 TCP Socket 的对比
| 对比项 | Unix Socket | TCP Socket |
|---|---|---|
| 通信范围 | 本机进程 | 跨主机 |
| 地址形式 | 文件路径(如 /var/run/app.sock) |
IP + 端口 |
| 协议栈 | 不经过 TCP/IP | 完整 TCP/IP |
| 性能 | 更高(低延迟、低开销) | 相对较低 |
| 安全性 | 依赖文件权限控制 | 依赖防火墙、认证等 |
| 是否可路由 | 否 | 是 |
三、Unix Socket 的工作原理
-
服务端
-
创建 socket:
socket(AF_UNIX, SOCK_STREAM, 0) -
绑定文件路径:
bind("/tmp/app.sock") -
监听并接受连接:
listen()/accept()
-
-
客户端
-
创建 socket
-
连接到该文件路径:
connect("/tmp/app.sock")
-
-
数据传输
-
使用
read/write或send/recv -
数据在内核中直接在进程之间传递
-
四、Unix Socket 的两种主要类型
1. SOCK_STREAM(流式,类似 TCP)
-
面向连接
-
保证顺序、可靠传输
-
常用于客户端/服务端模型
示例:
-
MySQL
-
Docker daemon
-
PHP-FPM
2. SOCK_DGRAM(数据报,类似 UDP)
-
无连接
-
消息边界保留
-
适合简单通知、日志类通信
五、典型使用场景(工程实践)
结合你日常接触的服务器/工控场景,Unix Socket 常用于:
1. 高性能本地服务通信
-
Nginx ↔ PHP-FPM
-
Docker CLI ↔ dockerd
-
systemd ↔ 各服务进程
示例:
bash
# php-fpm listen = /run/php/php-fpm.sock
bash
fastcgi_pass unix:/run/php/php-fpm.sock;
2. 本地安全通信
- 通过文件权限控制访问
bash
srw-rw---- 1 www-data www-data app.sock
- 非授权用户无法连接
3. 替代 TCP 的本机 RPC
-
避免端口冲突
-
降低系统资源消耗
-
提升吞吐量和响应速度
六、Unix Socket 的优势与限制
优势
-
性能高
-
延迟低
-
安全可控(文件权限)
-
配置简单,无需端口管理
限制
-
只能在本机使用
-
依赖文件系统
-
跨主机或容器隔离场景下受限(需 volume 挂载)
七、一个最简 C 语言示意(服务端)
cpp
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr = {0};
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, "/tmp/demo.sock");
bind(fd, (struct sockaddr*)&addr, sizeof(addr));
listen(fd, 5);
八、一句话总结
Unix Socket 是一种高效、安全、仅限本机的进程间通信机制,用文件路径代替网络地址,常用于本地服务之间的高性能通信。