76-抽象 unix 域套接字地址

1. 普通 VS 抽象

前面我们已经学习过了 sockaddr_un 结构,它有一个成员 sun_path,通常它保存的是一个以'\0'为结尾的绝对路径。一旦绑定了一个绝对路径,就会生成一个文件。这种 unix 域套接字地址我们称为普通 unix 域套接字地址

还有一种 unix 域套接字地址,它的特征是 sun_path[0] 是 null,即 sun_path[0] == '\0'. 这种 unix 域套接字地址称为抽象 unix 域套接字地址

2. 抽象 unix 域套接字地址

使用这种套接字地址,它并不会在文件系统中产生真正的套接字文件,而是由内核帮我们维护一个抽象套接字文件,它总是以 '@'开头,比如 @dog。所以,它的好处自然很明显,不用产生实际文件了。

既然 sun_path[0] == '\0',使用普通的方法就没办法得知抽象套接字文件的名字。unix 域协议规定使用套接字地址的长度来确定 sun_path.

比如套接字地址内容如下:

struct sockaddr_un addr = {   AF_LOCAL, // 长度为 2   {'\0', 'd', 'o', 'g'} // 长度为 4 }

则该 addr 的长度应该设置为 2 + 4 = 6.

在 bind 抽象 unix 域套接字地址的时候,不能再使用 sizeof(addr) 作为 bind 的最后一个参数了,而应该使用上面计算出来的 6 这个结果。

3. unix 域套接字长度计算

在 sys/un.h 有一个宏 SUN_LEN 可以计算该 addr 的长度:

#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen ((ptr)->sun_path))

不过我们不能直接在抽象的 unix 域套接字地址上使用它,因为这个宏使用到了 strlen 函数。使用的时候可以用下面的方法:

struct sockaddr_un addr; addr.sun_family = AF_LOCAL; strcpy(addr.sun_path + 1, "dog"); addr.sun_path[0] = '@'; // 先用非空字符占个位 len = SUN_LEN(&addr); // 计算长度 addr.sun_path[0] = 0; // 设置成抽象 unix 域套接字地址

4. 实验

程序路径:

git clone https://git.oschina.net/ivan_allen/unp.git

如果你已经 clone 过这个代码了,请使用 git pull 更新一下。本节程序所使用的程序路径是 unp/program/unixdomainprotocols/echo_stream.

4.1 实验步骤

  • 启动服务器
$ ./echo -s --path dog --abstract
  • 启动客户端
$ ./echo --path dog --abstract

4.2 实验结果及分析


这里写图片描述
图1 左侧是服务器,右侧是客户端


这里写图片描述
图2 netstat 输出

从图 2 中可以看到,Path 一栏显示的路径是 @dog,而不是 dog. 图 1 中显示的运行结果也很正常。

5. 总结

  • 普通 unix 域套接字地址和抽象 unix 域套接字地址
  • 如何创建抽象 unix 域套接字地址

说明:本文转自blog.csdn.net,用于学习交流分享,仅代表原文作者观点。如有疑问,请联系我们删除~