第十七章 高级进程间通信
2018-10-07 本文已影响19人
laidian
UNIX域套接字
UNIX 域套接字用于在同一台计算机上运行的进程之间的通信
虽然因特网域套接字可用于 同一目的,但 UNIX 域套接字的效率更高
UNIX 域套接字提供流和数据报两种接口
UNIX 域套接字就像是套接字和管道的混合
可以使用它们面向网络的域套接 字接口或者使用 socketpair 函数来创建一对无命名的、相互连接的 UNIX 域套接字
#include <sys/sock.h>
int socketpair(int domain,int type,int protocol,int sockfd[2]);
sockpair(AF_UNIX,SOCK_DGRAM,0,fd)
fd_pipe
借助 UNIX 域套接字轮询 XSI 消息队列
XSI 消息队列的使用存在一个问题,即不能将它们和 poll 或者 select 一起使用,这是因为它们不能关联到文件描述符
套接字是和文件描述符相关联的,消息到达时,可以用套接字来通知
- 创建了一些消息队列和 UNIX 域套接字,并 为每个消息队列开启了一个新线程
- 然后它在一个无限循环中用 poll 来轮询选择一个套接字端点
- 当某个套接字可读时,程序可以从套接字中读取数据
命名UNIX域套接字
.sock文件
将地址绑定到 UNIX 域套接字,系统会用该路径名创建一个 S_IFSOCK 类型的文件
UNIX 域套接字的地址由 sockaddr_un 结构 表示
#include "apue.h"
#include <sys/socket.h>
#include <sys/un.h>
int main(void)
{
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");
//确定绑定地址长度
//先计算 sun_path 成员在 sockaddr_un 结构中的偏移量
//然后将结果与路径名长度(不包括终止 null 字符)相加
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);
}
唯一连接
apue种开发的三个函数
#include “apue.h"
int serv_listen(const char *name);
int serv_accept(int listenfd,uid_t *uidptr);
int cil_conn(const char *name);
传送文件描述符
在技术上,我们是将指向一个打开文件表项的指针从一个进程发送到另外一个进程。该指针 被分配存放在接收进程的第一个可用描述符项中
#include "apue.h"
int send_fd(int fd,int fd_to_send);
int send_err(int fd,int status,const char *errmsg);
int recv_fd(int fd,ssize_t (*userfunc)(int ,const void *,size_t));