74-Unix 域套接字地址结构

1. unix 域协议简介

不同于 ipv4 的 AF_INET,unix 域只用于本机进程间通信,它所使用的完全是另一套协议。在使用 unix 域的时候,socket 函数的第一个参数必须指定为 AF_LOCAL 或者 AF_UNIX,表示创建一个 unix 域套接字。

2. sockaddr_un {}

不同于 ipv4 的 sockaddr_in{} 结构,unix 域的套接字地址结构为 sockaddr_un{},它包含在头文件 sys/un.h 中。


这里写图片描述
图1 sockaddr_un 的定义(linux 3.10 内核)

图 1 中的定义翻译出来就是下面这样:

struct sockaddr_un {
  unsigned short int sun_family;
  char sun_path[108];
}

算下来,这个结构体一共占用 110 个字节。

不同版本的实现可能稍有不同,比如在 unp 一书中介绍的 sun_path 成员只有 104 字节。POSIX 没有明确定义 sun_path 数组的大小。

sockaddr_un 成员里没有 ip 地址与端口号的概念,它的成员 sun_path 是某个具体的文件路径,该路径必须以'\0' 作为结尾。这种方式称为普通命名。

另一种方式是抽象命名,此时需要让 sun_path[0] = 0. 这个我们后面再说,这里我们先学会普通命名。

3. 示例——构造一个 unix 域套接字地址

构造这样的套接字地址非常简单:

struct sockaddr_un addr;
addr.sun_family = AF_UNIX; // 或者让它等于 AF_LOCAL,它们的值是一样的
strncpy(addr.sun_path, "/tmp/dog", sizeof(addr.sun_path) - 1);

注意:unix 域套接字关联的路径应该是一个绝对路径名,而不是相对路径(虽然在某些系统中相对路径能够正常工作,但我们不应该使用它)。POSIX 称给 unix 域套接字相对路径名将导致未定义行为。

4. 绑定 unix 域套接字

程序路径:

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

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

4.1 伪代码

int main() { 
  int sockfd, len;
  struct sockaddr_un addr1, addr2;

  // 注意第一个参数,必须是 AF_LOCAL 或者 AF_UNIX
  sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);

  // 如果文件已经存在,删除它
  unlink(pathname);            

  // 创建 unix 域套接字地址
  addr1.sun_family = AF_UNIX; 
  strncpy(addr1.sun_path, "/tmp/dog", sizeof(addr1.sun_path) - 1);  

  // 绑定套接字地址
  bind(sockfd, (struct sockaddr*)&addr1, sizeof(addr1));

  // 获取本地套接字地址,保存到 addr2 中
  len = sizeof(addr2);
  ret = getsockname(sockfd, (struct sockaddr*)&addr2, &len);

  printf("bound name = %s, returned len = %d\n", addr2.sun_path, len);

  return 0;
}

4.2 程序运行结果

unp/program/unixdomainprotocols/bindaddr 路径下,有一个 bindaddr 程序,这是我已经写好的。按照图 2 的方式运行:


这里写图片描述
图2 运行结果

我们看到程序 bindaddr 正常绑定了路径 /tmp/dog,同时生成了一个文件 /tmp/dog,注意观察前面的权限位,以 s 开头,表示这是一个 socket 文件。

5. 总结

  • 掌握创建 unix 套接字
  • 掌握 unix 域套接字地址的创建
  • 掌握 bind unix 套接字地址
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值