本文共 3450 字,大约阅读时间需要 11 分钟。
说到什么是域协议就会出现这么个解释:
UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所使用的API相同。UNIX域协议可以视为IPC方法之一。
我们白话解释下Unix域协议在什么情况下使用和怎么使用?
Unix域协议主要用在同一台机子的不同进程之间传递套接字。为什么不用TCP或者UDP套接字呢?一是因为快。源自Berkeley的实现中,Unix域套接字往往比通信两端位于同一个主机的TCP套接字快出一倍。二是因为安全。Unix套接字能提供额外的安全检查措施。
注意:Unix域协议表示协议地址的是路径名,而不是Inet域的IP地址和端口号
#includestruct sockaddr_un { sa_family_t sun_family; /*AF_LOCAL*/ char sun_path[104]; /*null-terminated pathname*/};
至于他们的程序和TCPsocket没有什么区别
Unix_Domain_ser.c #include#include #include #include #include #include #include #include int main(int argc, char *argv[]){ int listenfd1; struct sockaddr_un serv_addr1; //这里使用的AF_LOCAL代表是Unix域协议 listenfd1 = socket(AF_LOCAL, SOCK_STREAM, 0); bzero(&serv_addr1, sizeof(struct sockaddr_un)); serv_addr1.sun_family = AF_LOCAL; strncpy(serv_addr1.sun_path, argv[1], sizeof(serv_addr1.sun_path)-1); bind(listenfd1, (struct sockaddr *)&serv_addr1, SUN_LEN(&serv_addr1)); listen(listenfd1, 5); int clifd; char buffer[256]; //如果是listenfd1 获取消息 clifd = accept(listenfd1, NULL, NULL); bzero(buffer, 256); read(clifd, buffer, 255); printf("Listenfd1 Message is:%s\r\n", buffer); close(listenfd1); return 0;}
Unix_Domain_cli.c #include#include #include #include #include #include #include int main(int argc, char* argv[]){ int socketfd, n; socketfd = socket(AF_LOCAL, SOCK_STREAM, 0); struct sockaddr_un serv_addr; bzero((char *)&serv_addr, sizeof(serv_addr)); serv_addr.sun_family = AF_LOCAL; strncpy(serv_addr.sun_path, argv[1], sizeof(struct sockaddr_un)); connect(socketfd,(struct sockaddr *) &serv_addr, SUN_LEN(&serv_addr)); write(socketfd, "client message", 14); return 0;}
服务端命令:
客户端命令:
#include <sys/socket.h>
int socketpair(int family, int type, int protocol, int sockfd[2]);
1 socketpair创建两个socket,并连接起来,只用于Unix域
2 family参数必须为AF_LOCAL,protocol参数必须为0,
socketpair函数主要用在什么地方呢?当父进程fork出一个子进程的时候,两个进程需要使用Unix套接字进行进程间通信,那么socketpair就可以使用到了
发现说什么还是不如写代码实在:
Unix_Domain_Sockpair.c #include#include #include #include #include #include #include int main(int argc, char *argv[]){ int sockets[2]; char buffer[1024]; socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets); int child; child = fork(); if(child) { //父进程 close(sockets[0]); read(sockets[1], buffer, 255); printf("parent read--> %s\r\n", buffer); close(sockets[1]); } else { //子进程 close(sockets[1]); write(sockets[0], "Message", sizeof("Message")); printf("child write--> Message\r\n"); close(sockets[0]); } return 0;}
执行程序:
在nginx_process.c中你会看到这个:
这里得到几个信息:
1 Solaris 9 没有AF_LOCAL这个属性,所以使用AF_UNIX属性来代替
2 nginx每个worker进程之间都有channel通道,通道就是使用socketpair创建的
转载地址:http://dtpxx.baihongyu.com/