unix域套接字是linux系统中用于本地进程间通信的高效机制,它通过文件系统路径标识端点,不经过网络协议栈,具有更高的性能和安全性。支持流式(sock_stream)和数据报(sock_dgram)两种模式,常用于数据库服务、守护进程等本地服务通信场景。与tcp/ip套接字不同,uds仅在主机内部通信,避免了网络开销且更安全。创建uds服务端需调用socket()创建套接字,bind()绑定到指定路径(如/tmp/my_socket),listen()监听连接,accept()接收客户端连接并读取数据。客户端则通过socket()创建连接,connect()连接到服务端地址,并使用write()发送数据。编译c语言示例代码后,先运行服务端再运行客户端,可实现消息传递。注意事项包括:使用unlink()删除旧套接字文件防止绑定失败,设置适当权限控制访问,可通过ls查看套接字文件属性(类型为s)。掌握unix域套接字的基本流程有助于在高性能、高安全需求的应用中实现可靠的本地ipc通信。

Unix域套接字是Linux系统中实现本地进程间通信(IPC)的一种高效方式,它不经过网络协议栈,直接在操作系统内核中完成数据传输,因此比TCP/IP套接字更快速、更安全。适用于同一台机器上的进程通信,比如数据库服务与客户端、守护进程与管理工具之间的交互。
什么是Unix域套接字
Unix域套接字(Unix Domain Socket, 简称UDS)是一种用于在同一台主机上进行进程间通信的机制。它支持流式套接字(SOCK_STREAM)和数据报套接字(SOCK_DGRAM),类似于TCP和UDP,但只在本地使用,通过文件系统中的一个路径名来标识通信端点。
与网络套接字不同,Unix域套接字不会暴露在网络中,因此更加安全,且避免了网络开销。
创建Unix域套接字的服务端
以下是一个简单的C语言示例,展示如何编写一个使用流式Unix域套接字的服务端程序:
步骤说明:- 创建套接字:使用
socket(AF_UNIX, SOCK_STREAM, 0) - 绑定地址:将套接字绑定到一个文件路径(如
/tmp/my_socket) - 监听连接:调用
listen() - 接受连接并读取数据
服务端代码片段:
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int server_fd, client_fd;
struct sockaddr_un addr;
char buffer[1024];
// 创建Unix域套接字
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("socket");
exit(1);
}
// 设置地址结构
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, sizeof(addr.sun_path), "/tmp/my_socket");
// 如果套接字文件已存在,先删除
unlink(addr.sun_path);
// 绑定
if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("bind");
close(server_fd);
exit(1);
}
// 监听
if (listen(server_fd, 5) == -1) {
perror("listen");
close(server_fd);
exit(1);
}
printf("等待客户端连接...\n");
client_fd = accept(server_fd, NULL, NULL);
if (client_fd == -1) {
perror("accept");
close(server_fd);
exit(1);
}
// 读取客户端消息
int len = read(client_fd, buffer, sizeof(buffer)-1);
if (len > 0) {
buffer[len] = '\0';
printf("收到消息: %s\n", buffer);
}
// 清理
close(client_fd);
close(server_fd);
unlink(addr.sun_path); // 删除套接字文件
return 0;
}
编写客户端连接Unix域套接字
客户端程序负责连接到服务端创建的Unix域套接字,并发送数据。
客户端代码示例:
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int sock;
struct sockaddr_un addr;
const char *msg = "Hello from client";
// 创建套接字
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
perror("socket");
exit(1);
}
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, sizeof(addr.sun_path), "/tmp/my_socket");
// 连接到服务端
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("connect");
close(sock);
exit(1);
}
// 发送消息
write(sock, msg, strlen(msg));
close(sock);
return 0;
}
编译与运行方法
将上述服务端保存为server.c,客户端保存为client.c,然后使用gcc编译:
gcc server.c -o server gcc client.c -o client
启动服务端(在第一个终端中运行):
./server
再打开另一个终端,运行客户端:
./client
服务端应输出“收到消息: Hello from client”,表示通信成功。
注意事项与权限控制
- Unix域套接字对应的路径(如
/tmp/my_socket)需要有适当的读写权限,确保目标进程能访问。 - 每次绑定前建议调用
unlink()删除旧的套接字文件,避免“地址已被使用”错误。 - 可以使用
chmod修改套接字文件权限,或通过chown更改属主,实现访问控制。 - 调试时可用
ls /tmp/my_socket查看套接字文件(显示为srwxr-xr-x类型)。










