不同于 ipv4 的 AF_INET,unix 域只用于本机进程间通信,它所使用的完全是另一套协议。在使用 unix 域的时候,socket 函数的第一个参数必须指定为 AF_LOCAL 或者 AF_UNIX,表示创建一个 unix 域套接字。
不同于 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. 这个我们后面再说,这里我们先学会普通命名。
构造这样的套接字地址非常简单:
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 域套接字相对路径名将导致未定义行为。
程序路径:
git clone https://git.oschina.net/ivan_allen/unp.git如果你已经 clone 过这个代码了,请使用 git pull 更新一下。本节程序所使用的程序路径是 unp/program/unixdomainprotocols/bindaddr.
在 unp/program/unixdomainprotocols/bindaddr 路径下,有一个 bindaddr 程序,这是我已经写好的。按照图 2 的方式运行:
图2 运行结果我们看到程序 bindaddr 正常绑定了路径 /tmp/dog,同时生成了一个文件 /tmp/dog,注意观察前面的权限位,以 s 开头,表示这是一个 socket 文件。