结构体sockaddr_un:正确初始化

问题描述 投票:0回答:2

几天前,我遇到了一个与 struct sockaddr_un 相关的奇怪错误。有关更多信息,请阅读此处

过了一段时间,我也找到了该错误的解决方案,即简单地“memset”整个变量。现在我的问题是,正如那边的一篇文章已经提出的那样,为什么? 为什么我需要将整个本地变量而不是动态分配的变量设置为 0,即使我已将每个成员设置为合法且正确的值?

在其他

struct

中(例如 struct sockaddr_in)是一个变量,它用作填充,以便在内部看起来与 struct sockaddr 相同。你必须用 0 来填充(或者也许你不需要?请纠正我)该变量,以便使程序随时正确运行。 另外,哪里可以查看像connect()这样的源代码?难道是 connect() 函数没有完全实现吗?还是我缺少一些基础知识?

提前谢谢您。

c++ c unix-socket
2个回答
1
投票

unix_stream_connect源代码

来看,似乎没有任何将结构归零的要求。我编写了一个测试程序,有意用一个值填充结构,其中客户端和服务器传递不同的填充值,并且它们能够很好地相互连接:
void init_addr (struct sockaddr_un *addr, const char *path, int I) { struct sockaddr_un tmp = { .sun_family = AF_UNIX }; // fill sun_path memset(tmp.sun_path, I, UNIX_PATH_MAX); // copy path snprintf(tmp.sun_path, UNIX_PATH_MAX, "%s", path); *addr = tmp; }

可能导致连接失败的是竞争条件,即当客户端尝试
connect

时,服务器尚未完成其设置。

    


0
投票

首先,如果您不使用匿名名称(文件名不以 0 开头),那么您不需要清除结构。

如果您使用匿名名称,则取决于您是否将“len”参数传递给各个调用,如“sizeof(sockaddr_un)”或类似“len = strlen(local.sun_path+1) +1 + sizeof( local.sun_family); (这很丑陋,因为它忽略了可能的结构打包问题)。

对于匿名名称,套接字名称包括第一个 0 之后的所有字符,直到结构末尾(由 len 定义)。因此,如果将 len 作为 sizeof(sockaddr_un) (推荐)传递,则需要整个 sun_path 在两个调用之间匹配,因此需要将结构清零(或以相同方式设置结构)。

为了获得最佳结果、可读性和可移植性,您应该使用 len = sizeof(sockaddr_un),并在初始化之前将 sockaddr_un 设置为 0。

这篇文章应该会有帮助:

无法连接到Linux“抽象”unix套接字

© www.soinside.com 2019 - 2024. All rights reserved.