Linux   发布时间:2022-04-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了linux – Unix域套接字:accept()没有设置sun_path大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

我正在使用Unix域套接字进行一些测试,我可以毫无问题地通过它们进行通信,但是,当我在测试程序的服务器端调用accept()时,返回的struct sockaddr_un不包含sun_path.我很确定Inet套接字在accept()调用之后正确地填写了地址和端口,所以我在测试程序中做错了什么,或者我期待错误的结果?我正在运行CentOS 6.2和gcc 4

我正在使用Unix域套接字进行一些测试,我可以毫无问题地通过它们进行通信,但是,当我在测试程序的服务器端调用accept()时,返回的struct sockaddr_un不包含sun_path.

我很确定Inet套接字在accept()调用之后正确地填写了地址和端口,所以我在测试程序中做错了什么,或者我期待错误的结果?

我正在运行CentOS 6.2和gcc 4.4.6.

示例代码

server.c

#include <>dio.h>
#include < 0)="" {="">opening stream socket");
        exit(1);
    }

    server.sun_family = AF_UNIX;
    strcpy(server.sun_path,Name);

    if (bind(sock,(struct sockaddr *) &server,sizeof(struct sockaddr_un))) {
        perror("binding stream socket");
        exit(1);
    }

    printf("Socket has name %s\n",server.sun_path);
    listen(sock,5);

    for (;;) {
        socklen_t len = sizeof(client);
        msgsock = accept(sock,(struct sockaddr *)&client,&len);

        if (msgsock == -1)
            perror("accept");
        else do {
            printf("strlen(sun_path) = %zu\n",strlen(client.sun_path));

            bzero(buf,sizeof(buf));
            if ((rval = read(msgsock,buf,1024)) < 0)="" perror("reading="" stream="" message");="" else="" if="" (rval="=" 0)="" printf("ending="" connection\n");="" else="">%s\n",buf);
        } while (rval > 0);

        close(msgsock);
    }
    close(sock);
    unlink(Name);

    return 0;
}

client.c

#include <>dio.h>
#include < 2)="" {="">%s < 0)="" {="" close(sock);="" perror("connecting="" stream="" socket");="" exit(1);="" }="" if="" (write(sock,data,sizeof(data))="">< 0)="" perror("writing="" on="" stream="" socket");="" close(sock);="" return="" 0;="" }="">

只是重申一下这个问题:

为什么在服务器上的accept()调用之后没有填写sun_path?

最佳答案
我真的不确定这是否是一个答案.可能它更像是关于某些研究的思,尽管在阅读时可能仍然值得.

至少在Linux 3.16.0,NetBSD 6.1.4和Darwin 13.1.0内核中,accept(2)填充的值似乎与协议无关.在实践中,这意味着接受(2),struct sockaddr *的第​​二个参数仅被填充到所有协议之间共享的内容.因此,在成功接受(2)后你手中的东西远不是一个完整的结构sockaddr_un.

可能没有人认为在接受(2)的第一次实现完成时它会非常重要,现在我们仍然坚持这一点.幸运的是,有一种解决方法,如果有人丢失了用于socket的路径名并调用bind(2),现在又想找到它.

使用struct sockaddr_storage和getsockname(2),可以访问成员sun_path.因此,为了确保获得所有有用的细节,请在成功调用accept(2)之后调用getsockname(2)(这将在您的server.c中的第40行之后放置):

       struct sockaddr_storage ss;
       socklen_t sslen = sizeof(struct sockaddr_storagE);
       if (getsockname(msgsock,(struct sockaddr *)&ss,&sslen) == 0) {
               struct sockaddr_un *un = (struct sockaddr_un *)&ss;
               printf("socket name is: %s\n",un->sun_path);
       }

或者只是使用这个

#include <>dio.h>
#include %s\n",un->sun_path);
            }

            bzero(buf,buf);
        } while (rval > 0);

        close(msgsock);
    }
    close(sock);
    unlink(Name);

    return 0;
}

这已经过测试,即.它编译并产生预期的结果,用于运行内核3.16.0的GNU / Linux系统,运行6.1.4内核的NetBSD系统,以及运行13.1.0内核的OS / X Mavericks系统.在所有这些接受(2)的行为是一致的:sun_path在填充的结构中找不到. getsockname(2)的行为在不同的操作环境之间也是一致的,使所有协议特定的细节都可用.

大佬总结

以上是大佬教程为你收集整理的linux – Unix域套接字:accept()没有设置sun_path全部内容,希望文章能够帮你解决linux – Unix域套接字:accept()没有设置sun_path所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。