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))


这里写图片描述
图1 sys/un.h 中的源码

不过我们不能直接在抽象的 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 实验结果及分析


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


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

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

5. 总结

  • 普通 unix 域套接字地址和抽象 unix 域套接字地址
  • 如何创建抽象 unix 域套接字地址
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值