《UNIX环境高级编程》第17章 高级进程间通信

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jrc_january/article/details/74852904

17.1 引言

前面两章讨论了UNIX系统提供的各种IPC,其中包括管道和套接字。
本章介绍一个高级IPC-UNIX域套接字,并说明它的使用方法。
这种形式的IPC可以在同一计算机上运行的两个进程之间传送打开文件描述符。服务器进程可以使他们的打开文件描述符与指定的名字相关联,同一系统上运行的客户进程可以使用这些名字与服务器进程汇聚。

17.2 UNIX域套接字

UNIX域套接字用于在同一台计算机上运行的进程之间的通信。虽然因特网域套接字可用于同一目的,但UNIX域套接字的效率更高UNIX域套接字仅仅复制数据,它们并不执行协议处理、不需添加或删除网络报头、无需计算校验和、不需产生顺序号、无需发送确认报文。

可以是用socketpair函数来创建一对无命名的、相互连接的UNIX域套接字。

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

一对相互连接的UNIX域套接字可以起到全双工管道的作用:两端对读和写开放。我们称其为fd管道(fd-pipe),以便区分普通管道。

命名UNIX域套接字

虽然socketpair函数能创建一对相互连接的套接字,但每一个套接字都没有名字。这意味着无关进程不能使用它们。
恰如可以将一个地址绑定到一个因特网域套接字上,可以命名UNIX域套接字。但要注意,UNIX域套接字地址不同于因特网域套接字。
UNIX域套接字地址由sockaddr_un结构表示。

struct sockaddr_un{
sa_family_t sun_family; //AF_UNIX
char        sun_path[108];  //pathname
};

sockaddr_un结构的sun_path成员包含一个路径名。当我们将一个地址绑定到一个UNIX域套接字是,系统会用该路径名创建一个S_IFSOCK类型的文件。
该文件仅用于向客户进程告示套接字名字。该文件无法打开,也不能由应用程序用于通信。

#include <sys/socket.h>
#include <sys/un.h>

#define offsetof(TYPE,MEMBER) ((int)&((TYPE *)0)->MEMBER)
int main()
{
int fd,size;
struct sockaddr_un un;
un.sun_family=AF_UNIX;
strcpy(un.sun_path,"foo.socket");

if((fd=socket(AF_UNIX,SOCK_STREAM,0))<0)
err_sys(:socket failed");

size=offsetof(struct sockaddr_un,sun_path)+strlen(un.sun_path);

if(bind(fd,(struct sockaddr *)&un,size)<0)
err_sys("bind failed");
printf("UNIX domain socket bound.\n");
exit(0);
}

17.3 唯一链接

服务器进程可以使用标准bind、listen和accept函数,为客户进程安排一个唯一UNIX域连接。客户进程使用connect与服务器进程联系。在服务器进程接收了connect请求后,在服务器进程和客户进程之间就存在了唯一连接。这种风格与因特网域套接字的操作相同。

17.4 传送文件描述符

在两个进程之间传送打开文件描述符的技术是非常有用的。它使一个进程能够处理打开一个文件所要做的一切操作以及向调用进程送回一个描述符,该描述符可以被用于以后的所有IO函数。


下面进一步说明从一个进程向另一个进程传送一个开打文件描述符的含义。如下图,显示了两个进程,它们打开了同一文件。虽然它们共享一个v节点,但每个进程都有他自己的文件表项。
当一个进程向另一个进程传送一个打开文件描述符时,我们想让发送进程和接收进程共享同一文件表项。
这里写图片描述

17.5 open服务器进程第1版

略。

17.6 open服务器进程第2版

略。

17.7 小结

本章的关键点是如何在两个进程之间传送文件描述符,以及服务器进程如何接收来自客户进程的唯一连接。
虽然所有平台都支持UNIX域套接字,但是各种实现都有不同之处,这使我们很难开发可移植的应用程序。

猜你喜欢

转载自blog.csdn.net/jrc_january/article/details/74852904
今日推荐