是的,Linux会自动“清理”抽象套接字,以至于清理甚至有意义。这是一个最小的工作示例,您可以通过此示例进行验证:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
int
main(int argc, char **argv)
{
int s;
struct sockaddr_un sun;
if (argc != 2 || strlen(argv[1]) + 1 > sizeof(sun.sun_path)) {
fprintf(stderr, "usage: %s abstract-path\n", argv[0]);
exit(1);
}
s = socket(AF_UNIX, SOCK_STREAM, 0);
if (s < 0) {
perror("socket");
exit(1);
}
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path + 1, argv[1]);
if (bind(s, (struct sockaddr *) &sun, sizeof(sun))) {
perror("bind");
exit(1);
}
pause();
}
以运行该程序./a.out /test-socket &
,然后运行ss -ax | grep test-socket
,您将看到正在使用的套接字。然后kill %./a.out
,ss -ax
将显示套接字已消失。
但是,在任何文档中都找不到此清理的原因是,它实际上不是以非抽象的unix域套接字需要清理的方式清理。非抽象套接字实际上会分配一个inode并在目录中创建一个条目,需要在基础文件系统中清除该条目。相比之下,将抽象套接字想像成TCP或UDP端口号。当然,如果您绑定一个TCP端口然后退出,则该TCP端口将再次释放。但是您使用的任何16位数字仍然抽象存在并且始终存在。端口号的名称空间是1-65535,并且从不更改或需要清洗。
因此,只需将抽象套接字名称想像为TCP或UDP端口号,就可以从一组更大的可能看起来像路径名而不是路径名的端口号中选择。您不能两次绑定相同的端口号(禁止SO_REUSEADDR
或SO_REUSEPORT
)。但是关闭套接字(显式或隐式终止)可以释放端口,而无需清理任何内容。