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#include #include #include #include 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#include #include #include #include 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类型)。









