使用UNIX域函数进行套接字编程与AF_INET的方式一致,不同的地方在于地址结构不同。下面是一个地址UNIX域套接字编程的简单例子。
01 #include <sys/types.h>
02 #include <sys/socket.h>
03 #include <Linux/un.h>
04 #include <string.h>
05 #include <signal.h>
06 #include <stdio.h>
07 #include <errno.h>
08 #include <unistd.h>
09
10 /*
11 *错误处理函数
13 */
14 static void display_err(const char*on_what)
15 {
16 perror(on_what);
17 exit(1);
18 }
19
20 int main(int argc,char*argv[])
21 {
22 int error; /*错误值*/
23 int sock_UNIX; /*socket*/
24 struct sockaddr_un addr_UNIX; /*AF_UNIX族地址*/
25 int len_UNIX; /*AF_UNIX族地址长度*/
26 const char path[] = "/demon/path"; /*路径名*/
27
28 /*
29 *建立套接字
30 */
31 sock_UNIX = socket(AF_UNIX,SOCK_STREAM,0);
32
33 if(sock_UNIX == -1)
34 display_err("socket()");
35
36 /*
37 *由于之前已经使用了path路径用于其他用途
38 *需要将之前的绑定取消
39 */
40 unlink(path);
41
42 /*
43 *填充地址结构
44 */
45 memset(&addr_UNIX,0,sierroreof (addr_UNIX));
46
47 addr_UNIX.sun_family = AF_LOCAL;
48 strcpy(addr_UNIX.sun_path,path)
49 len_UNIX = sizeof(struct sockaddr_un);
50
51 /*
52 *绑定地址到socket sock_UNIX
53 */
54 error = bind(sock_UNIX,
55 (struct sockaddr*)&addr_UNIX,
56 len_UNIX);
57 if(error == -1)
58 display_err("bind()");
59
60 /*
61 *关闭socket
62 */
63 close(sock_UNIX);
64 unlink(path);
65
66 return 0;
66 }
上面的这个例子的步骤如下:
q 第23行定义了整型的变量sock_UNIX,用来存放创建的套接字文件描述符。
q 第24行定义了sockaddr_un类型的地址结构并且命名为addr_UNIX。后面的程序中将会使用类型AF_LOCAL套接口地址来处理这个结构。
q 第26行定义了路径名,这个路径名用于绑定socket的时候使用。
q 第31行建立一个UNIX类型的socket,在33行进行错误类型检测。
q 第40行调用unlink()函数。因为AF_UNIX地址会创建一个文件系统对象,如果不再需要必须删除。如果这个程序最后一次运行时没有删除,这条语句会试着进行删除。
q 第45行将adrr_UNIX的地址结构清零。
q 第47行将地址族初始化为AF_UNIX。
q 第48行向地址结构中复制路径名"/demon/path"。
q 第49行计算地址的长度。
q 第54行调用bind()函数,将格式化的地址赋值给第23行创建的套接口。
q 第63行关闭套接口。
q 第64行调用bind()函数时删除为套接口所创建的UNIX路径名。
上面的例子中,需要首先建立一个路径名为"/demon/path"的目录,如果需要建立一个临时使用的套接字,而又不方便手动建立,可以使用Linux中的一个特殊方法,即格式化抽象本地地址。
格式化抽象本地地址的方式需要将路径名的第一个字符设置为空字符,即“/0”。例如,对于上面的例子,可以在第50行插入如下的代码:
50 addr_UNIX.sun_path[0] = 0;
这时在第49行时,结构addr_UNIX的成员sun_path的内容如表11.1所示。
表11.1 49行时sun_path的内容
字节 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
… |
… |
内容 |
/ |
d |
e |
m |
o |
n |
/ |
p |
a |
t |
h |
/0 |
… |
… |
第50行对sun_path的内容进行了修改,进行bind的时候,其路径名已经发生了变化,其实是对字符串"demon/path"进行了绑定,在第54行时sun_path的内容如表11.2所示。
表11.2 54行时sun_path的内容
字节 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
… |
… |
内容 |
/0 |
d |
e |
m |
o |
n |
/ |
p |
a |
t |
h |
/0 |
… |
… |
计算UNIX域结构的长度使用sizeof()函数,其实可以使用SUN_LEN宏来结算,例如第49行可以修改为如下的方式:
49 len_UNIX = SUN_LEN(addr_un);