作文素材网站,怎么做网站排名会更好,怎样找外贸公司合作,在网站上做外贸✅ 一、UDS 是什么#xff1f;UDS Unix Domain Socket#xff08;也叫 IPC Socket,也叫域内通信#xff09;它是 Linux/Unix 系统中一种进程间通信#xff08;IPC#xff1a;Inter-Process Communication#xff09;机制#xff0c;用于同一台机器上的两个进程之间通信…✅ 一、UDS 是什么UDS Unix Domain Socket也叫 IPC Socket,也叫域内通信它是 Linux/Unix 系统中一种进程间通信IPCInter-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_DGRAMAF_UNIX表示使用 Unix Domain SocketSOCK_STREAM→ 类似 TCP可靠、有序SOCK_DGRAM→ 类似 UDP无连接、消息边界核心真相UDS的TCP/UDP是内核IPC1.网络栈 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_INETAF_INETIPv4 网络协议最常用AF_INET6AF_INET6IPv6 网络协议AF_UNIXAF_UNIX/AF_LOCAL本地进程间通信AF_PACKETAF_PACKET底层数据包接口2. type套接字类型值常量说明1SOCK_STREAM面向连接的可靠字节流TCP2SOCK_DGRAM无连接不可靠数据报UDP3SOCK_RAW原始套接字直接访问网络层2. 绑定地址服务端UDS 的“地址”文件通常是一个文件系统路径如/tmp/mysocketstruct 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 SocketUDS文件只是一个“命名标识符”name endpoint并不用于存储通信数据。它的作用类似于 TCP 中的 “IP 地址 端口号”—— 只是用来标识一个通信端点而不是数据容器实际数据不写入磁盘例如ls -l/tmp/mysocketsrwxrwxr-x 1 XX XX012月 17 16:18 /tmp/mysocket备注uds地址文件由调用bind()的进程创建通常是服务端bind()成功返回该 socket 文件就出现在文件系统中。如果路径已存在同名文件比如上次崩溃没清理bind()会失败返回-1errno 为EADDRINUSE。所以通常服务端会在bind()前先unlink()。注意客户端不需要也不应该创建这个文件。客户端只通过路径去connect()。服务端进程退出自动销毁。3. 连接客户端客户端也创建AF_UNIXsocketconnect()到与服务端同一个uds路径如/tmp/mysocketconnect(sockfd, (struct sockaddr*)addr, sizeof(addr));4. 通信之后就可以用read()/write()或send()/recv()像普通 socket 一样收发数据。5. 清理通信结束后服务端应unlink(/tmp/mysocket)删除 socket 文件避免残留。6.完整的 C 语言 Unix Domain SocketUDS示例服务端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.sockReceived: Hello from client!Server shutdown.客户端打印Sent: Hello from client!Received echo: Hello from client!