nginx源码学习Unix - Unix域协议
說到什么是域協議就會出現這么個解釋:
UNIX域協議并不是一個實際的協議族,而是在單個主機上執行客戶/服務器通信的一種方法,所用API與在不同主機上執行客戶/服務器通信所使用的API相同。UNIX域協議可以視為IPC方法之一。
?
我們白話解釋下Unix域協議在什么情況下使用和怎么使用?
Unix域協議主要用在同一臺機子的不同進程之間傳遞套接字。為什么不用TCP或者UDP套接字呢?一是因為快。源自Berkeley的實現中,Unix域套接字往往比通信兩端位于同一個主機的TCP套接字快出一倍。二是因為安全。Unix套接字能提供額外的安全檢查措施。
注意:Unix域協議表示協議地址的是路徑名,而不是Inet域的IP地址和端口號
socket地址結構:
#include<sys/un.h> struct sockaddr_un {sa_family_t sun_family; /*AF_LOCAL*/char sun_path[104]; /*null-terminated pathname*/ };至于他們的程序和TCPsocket沒有什么區別
服務器端:
Unix_Domain_ser.c #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <unistd.h> #include <sys/un.h> #include <sys/select.h>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 <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <string.h> #include <unistd.h> #include <sys/un.h>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;}服務端命令:
客戶端命令:
參考文檔:
http://memorymyann.iteye.com/blog/649619
http://hi.baidu.com/wangjianzhong1981/blog/item/d91d1c1073b2e409203f2e4d.html
socketpair函數
#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 <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <unistd.h> #include <sys/un.h>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中的socketpair使用:
在nginx_process.c中你會看到這個:
這里得到幾個信息:
1 Solaris 9 沒有AF_LOCAL這個屬性,所以使用AF_UNIX屬性來代替
2 nginx每個worker進程之間都有channel通道,通道就是使用socketpair創建的
總結
以上是生活随笔為你收集整理的nginx源码学习Unix - Unix域协议的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android文件Apk下载变ZIP压缩
- 下一篇: Java输入输出流和文件操作