1. UNIX域套接字
1.1 概念
这种形式的IPC可以在同一计算机系统上运行的两个进程之间传送打开文件描述符
-
UNIX域套接字用于在同一台计算机上运行的进程之间的通信。这里要和第十六章介绍的内容区别,第十六章介绍的是因特网域套接字,而这里介绍UNIX域套接字,即通信域不同。因特网域主要应用于不同主机进程间通信,UNIX域只能应用于同一台主机上进程间的通信。
-
虽然因特网域套接字也可用于同一计算机进程间通信,但是UNIX域套接字效率更高。因为UNIX域套接字不需要TCP/IP网络协议栈处理,UNIX域套接字仅仅是复制数据,不执行协议处理,不需要添加或删除网络报头,无需计算校验和,不产生顺序号,无需发送确认报文。
-
UNIX域套接字提供基于字节流和基于数据报的两种接口。UNIX域套接字的数据报服务是可靠的,即不会丢失报文,不会传递出错。
-
UNIX域套接字就像是套接字和管道的混合。可以使用因特网域套接字接口(十六章介绍的bind、connect等函数),或者使用socketpair函数来创建一对无命名的、相互连接的UNIX域套接字。
1.2 无命名UNIX域套接字(socketpair函数)
使用socketpair函数来创建一对无命名的、相互连接的UNIX域套接字。类比于pipe函数
因为套接字是匿名的,因此只能用于相关进程间通信。
int socketpair(int domain, int type, int protocol, int sv[2]);
- 参数domain:通信域,在Linux下只能为AF_LOCAL或者AF_UNIX
- 参数type:套接字类型,既可以是SOCK_STREAM,又可以是SOCK_DGRAM,当参数指定为SOCK_STREAM时,得到的结果称为流管道,它与一般管道的区别是流管道是全双工的,即两个描述符既可读又可写
- 参数protocol:协议类型,只能是0
- 参数cv[2]:保存分配的两个UNIX域套接字
由该函数创建的一对未命名的UNIX域套接字,可以起到全双工管道的作用:两端都对读和写开放。
其实有些系统使用UNIX域套接字实现匿名管道:关闭第一描述符的写端和第二描述符的读端。
1.3 命名UNIX域套接字
未命名套接字由于没有名字,因此只能用于有关进程间通信,不能用于无关进程间通信。
上一章中介绍了bind函数可以将一个地址绑定到一个因特网域套接字上。对于命名UNIX域套接字,也可以使用bind函数将其绑定到一个路径上,但是注意,命名UNIX域套接字绑定的地址格式不同于因特网域套接字。
命名UNIX域套接字的绑定的地址格式由sockaddr_un结构表示,该结构体指针在传递给bind函数时也要转换为sockaddr指针类型。
struct sockaddr_un
{
sa_family_t sun_family; /* 地址族:AF_UNIX */
char sun_path[108</