はい、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ドメインソケットのクリーンアップが必要なのと同じ意味で実際にはクリーンアップされていないためです。非抽象ソケットは実際にiノードを割り当て、ディレクトリにエントリを作成します。このエントリは、基礎となるファイルシステムでクリーンアップする必要があります。対照的に、TCPまたはUDPポート番号のような抽象ソケットを考えてください。もちろん、TCPポートをバインドして終了すると、そのTCPポートは再び解放されます。ただし、使用した16ビットの数値は抽象的に存在し、常に存在していました。ポート番号の名前空間は1〜65535であり、変更したり、クリーニングする必要はありません。
したがって、TCPまたはUDPポート番号のような抽象的なソケット名を考えてみてください。パス名のように見えるがそうではない可能性のあるはるかに大きなポート番号のセットから選択されただけです。同じポート番号を2回バインドすることはできません(禁止SO_REUSEADDR
またはSO_REUSEPORT
)。ただし、ソケットを閉じると(明示的または暗黙的に終了することで)ポートが解放され、クリーンアップするものは何も残りません。