nginx源码学习Unix - Unix域协议

简介:

说到什么是域协议就会出现这么个解释:

UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所使用的API相同。UNIX域协议可以视为IPC方法之一。

 

我们白话解释下Unix域协议在什么情况下使用和怎么使用?

Unix域协议主要用在同一台机子的不同进程之间传递套接字。为什么不用TCP或者UDP套接字呢?一是因为快。源自Berkeley的实现中,Unix域套接字往往比通信两端位于同一个主机的TCP套接字快出一倍。二是因为安全。Unix套接字能提供额外的安全检查措施。

注意:Unix域协议表示协议地址的是路径名,而不是Inet域的IP地址和端口号

socket地址结构:

1
2
3
4
5
#include<sys/un.h>
struct sockaddr_un {
     sa_family_t sun_family; /*AF_LOCAL*/
     char  sun_path[ 104 ];     /*null-terminated pathname*/
};

至于他们的程序和TCPsocket没有什么区别

服务器端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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 ;
 
}

客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 ;
 
}

服务端命令:

clip_image001

客户端命令:

clip_image002

参考文档:

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就可以使用到了

发现说什么还是不如写代码实在:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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 ;
 
}

执行程序:

clip_image003

nginx中的socketpair使用:

在nginx_process.c中你会看到这个:

clip_image004

这里得到几个信息:

1 Solaris 9 没有AF_LOCAL这个属性,所以使用AF_UNIX属性来代替

2 nginx每个worker进程之间都有channel通道,通道就是使用socketpair创建的


本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2012/06/08/2541401.html,如需转载请自行联系原作者


相关文章
|
16天前
|
应用服务中间件 Linux 网络安全
CentOS 7.4源码编译nginx1.12 并且隐藏nginx的版本
CentOS 7.4源码编译nginx1.12 并且隐藏nginx的版本
15 0
|
18天前
|
负载均衡 应用服务中间件 数据处理
Nginx学习使用
Nginx学习使用
38 0
|
6月前
|
网络协议 应用服务中间件 nginx
nginx配置tcp协议代理的日志
nginx配置tcp协议代理的日志
148 0
|
6月前
|
应用服务中间件 网络安全 nginx
Nginx学习研究-Nginx 安装 SSL 配置 HTTPS
Nginx学习研究-Nginx 安装 SSL 配置 HTTPS
269 0
|
3月前
|
算法 应用服务中间件 nginx
NGINX下的红黑树源码详解(附 流程图和GIF)(1)
之前博主稍微讲解了下红黑树的原理,那么在这篇博客博主想要把红黑树讲的更加的透彻,以便于更多的人了解红黑树 (本博客会更加详细的介绍之前的博客没介绍到的,所以各位看官不同再回去翻看博主之前那篇红黑树的原理讲解了。)
39 3
|
2月前
|
缓存 负载均衡 安全
Nginx 学习
Nginx 学习
30 0
|
3月前
|
tengine 应用服务中间件 nginx
Tengine有没有非开源的支持nginx的steam quic协议?
【1月更文挑战第15天】【1月更文挑战第75篇】Tengine有没有非开源的支持nginx的steam quic协议?
45 10
|
3月前
|
应用服务中间件 nginx
Nginx源码阅读:共享内存ngx_shm_t和它的组织方式ngx_shm_zone_t、ngx_list_t
Nginx源码阅读:共享内存ngx_shm_t和它的组织方式ngx_shm_zone_t、ngx_list_t
24 0
|
3月前
|
应用服务中间件 nginx
Nginx源码阅读:ngx_list_t 链表
Nginx源码阅读:ngx_list_t 链表
52 0
|
3月前
|
存储 应用服务中间件 nginx
Nginx模块开发:模块结构的源码阅读以及过滤器(Filter)模块的实现
Nginx模块开发:模块结构的源码阅读以及过滤器(Filter)模块的实现
65 0