说到什么是域协议就会出现这么个解释:
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
;
}
|
服务端命令:
客户端命令:
参考文档:
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
;
}
|
执行程序:
nginx中的socketpair使用:
在nginx_process.c中你会看到这个:
这里得到几个信息:
1 Solaris 9 没有AF_LOCAL这个属性,所以使用AF_UNIX属性来代替
2 nginx每个worker进程之间都有channel通道,通道就是使用socketpair创建的
本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2012/06/08/2541401.html,如需转载请自行联系原作者