从命令行创建 Unix 命名套接字

从命令行创建 Unix 命名套接字

是否有类似于 mkfifo 但用于域套接字的命令?

答案1

对于套接字,没有与 mkfifo 完全相同的命令,即没有命令只创建“挂起”套接字。这是出于历史原因:如果名称已被使用,则服务器的 bind() 函数(在文件系统中创建套接字名称/inode 的函数)会失败。换句话说,服务器无法对预先存在的套接字进行操作。

因此,如果您之前创建了套接字,则无论如何都需要先由服务器将其删除。没有好处。正如您在 Gregory 的回答中看到的那样,如果您为其保留一个服务器(例如 netcat),则可以创建一个套接字。一旦服务器消失,旧套接字就消失了。新服务器有一个新的套接字,所有客户端都需要重新连接,尽管套接字的名称相同。

答案2

netcat在这种情况下,我只是使用并保持倾听:

nc -lkU aSocket.sock

你应该使用netcat-openbsdnetcat-传统没有-U用于 Unix 域套接字的开关。

答案3

最新的 netcat (nc) 和类似程序(据我所知是 socat)都有域套接字选项。
否则,您可以查看 ucspi-unix

答案4

在 Linux 上,创建这样的程序非常简单:

#include <sys/stat.h>
#include <stdio.h>
int main(int C, char **V){
    int r=0; while(*++V) if (mknod(*V,S_IFSOCK|0666,0)) r=1,perror(*V);
    return r;
}

mknod在 Linux 上也可以根据给定的S_IF...参数创建所有其他文件类型。

在其他 UNIXES 上,恐怕您需要执行相当复杂的操作:分配套接字文件、绑定它并删除描述符:

#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
int main(int C, char **V){
    int r=0; while(*++V){
        int sfd = socket(AF_UNIX,SOCK_DGRAM,0);
        if (0>sfd){ perror("socket"); goto fail; }
        struct sockaddr_un a; a.sun_family = AF_UNIX;
        size_t len = strlen(*V);
        if (len+1 > sizeof(a.sun_path)){ errno=ENAMETOOLONG, perror("bind"); goto close_and_fail; }
        memcpy(a.sun_path,*V,len+1);
        socklen_t socklen = (socklen_t)(len+1+offsetof(struct sockaddr_un,sun_path));
        if (0>bind(sfd,(void*)&a,socklen)) perror("bind");
        else{ close(sfd); continue; }

        close_and_fail:
        close(sfd);
        fail: r=1;
    }
    return r;
}

不过,正如前面所说,创建这样的孤立套接字文件并不是很有用。它肯定不能用作套接字地址(该套接字文件的新服务器需要先取消链接),但它将测试(test -S file/[ -S file ]作为套接字类型的文件,在某些脚本中可能有用。

相关内容