重用 linux 抽象命名空间套接字

Posted

技术标签:

【中文标题】重用 linux 抽象命名空间套接字【英文标题】:Reusing linux abstract namespace socket 【发布时间】:2017-06-06 17:36:15 【问题描述】:

我想在一个服务器会话期间重用一个抽象套接字地址。我试图关闭套接字并再次绑定它们,但它不起作用。

server.c:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

int main()

    struct sockaddr_un workmanaddr;
    workmanaddr.sun_family=AF_UNIX;
    strcpy(workmanaddr.sun_path+1,"name");
    workmanaddr.sun_path[0]='0';
    char buf[255];
    int sd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if(sd <0)
    
        perror("socket() error");
        exit(2);
    
    if((bind(sd , (struct sockaddr *)&workmanaddr,sizeof(workmanaddr)))<0)
    
        perror("bind() error");
        exit(3);
    
    while(true)
    
        recv(sd, buf, sizeof(buf), 0);
        printf("%s\n",buf);
        close(sd);
        sd = socket(AF_UNIX, SOCK_DGRAM, 0);
        if(sd <0)
        
            perror("socket() error");
            exit(2);
        
        if((bind(sd , (struct sockaddr*)&workmanaddr,sizeof(workmanaddr)))<0)
        
            perror("bind() error");
            exit(3);
                
    
    return 0;

client.c:

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
int main(int argc, char *argv[])

    char _path[108]="name";
    struct sockaddr_un tempadres = 0;
    int tmpsock;
    tmpsock = socket(AF_UNIX, SOCK_DGRAM, 0);
    if(tmpsock<0)
    
        perror("socket() error");
        exit(2);
    
    tempadres.sun_family=AF_UNIX;
    strcpy(tempadres.sun_path+1,_path);
    tempadres.sun_path[0]='0';
     if((connect(tmpsock, (struct sockaddr *)&tempadres,sizeof(tempadres)))<0)
     
         perror("connect() error");
         exit(3);
     
    char buf[255];
        scanf("%s",buf);
        if(send(tmpsock, buf, sizeof(buf), 0)<0)
        
            perror("send() error");
            exit(4);
        
    return 0;

我应该怎么做才能使其可以多次重复使用?有什么建议吗?

【问题讨论】:

“它不起作用”是什么意思?您预计会发生什么以及实际会发生什么? 相关:unix.stackexchange.com/questions/216784/… tempadres.sun_path[0]='0'; '0' 不是空字节! 【参考方案1】:

在这一行中:tempadres.sun_path[0]='0','0' 不是空字节,这是抽象套接字对sun_path 字段的第一个字节所要求的。所以它不会被视为抽象套接字。将其更改为 tempadres.sun_path[0]=0tempadres.sun_path[0]='\0'


PS:你的server.c还有一个问题,你没有把workmanaddr归零,所以sun_path很可能包含垃圾值,因为它是在堆栈上分配的即使您调用了strcpy(workmanaddr.sun_path+1,"name"); 并附加了一个空字节,因为sun_path 中的所有剩余字节都定义了套接字的“名称”。这会导致与客户端的套接字名称不同,从而导致客户端拒绝连接。

【讨论】:

以上是关于重用 linux 抽象命名空间套接字的主要内容,如果未能解决你的问题,请参考以下文章

PHP之命名空间

PHP之命名空间

如何在 Django 命名空间可重用应用程序中进行反向 URL 搜索

来自不同命名空间的同名对象的可重用函数代码?

命名空间

命名空间