一。Unix domain socket概念
socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。
UNIX Domain Socket是全双工的,API接口语义丰富,相比其它IPC机制有明显的优越性,目前已成为使用最广泛的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIXDomain Socket通讯的。
二。本地套接字地址结构
struct sockaddr_un {
__kernel_sa_family_t sun_family; /* AF_UNIX */ 地址结构类型
char sun_path[UNIX_PATH_MAX]; /* pathname */ socket文件名(含路径)
};
三。代码示例
服务端
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <sys/socket.h> 4 #include <strings.h> 5 #include <string.h> 6 #include <ctype.h> 7 #include <arpa/inet.h> 8 #include <sys/un.h> 9 #include <stddef.h> 10 11 #include "wrap.h" 12 13 #define SERV_ADDR "serv.socket" 14 15 int main(void) 16 { 17 int lfd, cfd, len, size, i; 18 struct sockaddr_un servaddr, cliaddr; 19 char buf[4096]; 20 21 lfd = socket(AF_UNIX, SOCK_STREAM, 0); //本地套接字 AF_UNIX 22 23 bzero(&servaddr, sizeof(servaddr)); 24 servaddr.sun_family = AF_UNIX; //初始化地址信息 25 strcpy(servaddr.sun_path,SERV_ADDR); //套接字文件名 26 27 len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path); /* servaddr total len */ 28 //offsetof计算结构体中成员的偏移量,偏移量+文件名大小=结构体长度 29 30 31 unlink(SERV_ADDR); /* 确保bind之前serv.sock文件不存在,bind会创建该文件 */ 32 bind(lfd, (struct sockaddr *)&servaddr, len); /* 参3不能是sizeof(servaddr) */ 33 34 listen(lfd, 20); 35 36 printf("Accept ... "); 37 while (1) { 38 len = sizeof(cliaddr); 39 cfd = accept(lfd, (struct sockaddr *)&cliaddr, (socklen_t *)&len); 40 41 len -= offsetof(struct sockaddr_un, sun_path); /* 得到文件名的长度 */ 42 cliaddr.sun_path[len] = '