c语言 - 进程间通信 Unix Domain Socket

c语言 - 进程间通信 Unix Domain Socket

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接口,类似TCPUDP,但是面向数据报的UNIX Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱;

使用UNIX Domain Socket的过程和网络socket十分相似,也要先调用socket()创建一个socket文件描述符,address family指定为AF_UNIX,type可以选择SOCK_STREAMSOCK_DGRAM,protocol参数仍然指定为0即可;

UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示;
网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已经存在,则bind()错误返回;

Unix Domain Socket 示例

server.c

client.c

socketpair函数

socketpair()函数用于创建一个全双工的流管道

int socketpair(int domain, int type, int protocol, int sv[2]);

  • 头文件:sys/types.hsys/socket.h
  • domain:输入参数,协议族(AF_INET、AF_INET6、AF_UNIX),这里我们选择AF_UNIX;
  • type:输入参数,套接字类型(SOCK_STREAM、SOCK_DGRAM、SOCK_RAW),这里我们选择SOCK_STREAM;
  • protocol:输入参数,协议类型,一般置为0,让系统选择默认的协议;
  • sv[2]:输出参数,拥有2个元素的整型数组,返回一个套接字对;
  • 返回值:成功返回0,失败返回-1,并设置errno

实际上socketpair()pipe()函数是类似的,也只能在同个主机上具有亲缘关系的进程间通信;
pipe()创建的匿名管道是半双工的,而socketpair()可以认为是创建一个全双工的管道;
可以使用socketpair()创建返回的套接字对进行父子进程通信:

示例