我看到的每个地方,都会看到以下代码:
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = ip;
在C ++中,同样的想法通常表示为
sockaddr_in addr = {}; // unneccesary(?) value-initialzation
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = ip;
然而,无论我看起来(在官方文档方面),我都没有看到在设置这些成员之前将结构清零的要求!是的,通常BSD套接字实现确实为sin_zero
定义了sockaddr_in
成员,但是他们总是说填充需要成员,以便将sockaddr_in
的大小与sockaddr
对齐。他们从不要求任何人将任何特定内容放入其中。
是否有真实,文档证明需要将结构清零?
P.S。
在您将问题视为与memset
sockaddr_in
上有关#include<stdio.h>
int main()
{
char *a ="%d";
int c = 5;
printf(a,c);
}
的若干SO问题之一的重复之前,请确保您提出的重复问题与官方文档有任何关联,而不仅仅是猜测'初始化未使用的成员,以防万一'。
答案 0 :(得分:5)
IEEE标准不要求它。
IEEE Standard
1003.1指定sockaddr_in
的定义是(强调我的):
标题应定义sockaddr_in结构 包括至少以下成员:
sa_family_t sin_family AF_INET.
in_port_t sin_port Port number.
struct in_addr sin_addr IP address.
请注意,与sockaddr_in6
的定义不同,后者指定将 清零:
应用程序应将
sockaddr_in6
结构设置为零 在使用它之前,因为实现可以免费增加,sockaddr_in6
中的实现定义字段。
sockaddr_in
没有类似的措辞。然而,这种措辞的缺乏使得平台实现者有足够的模糊性来制定他们自己关于将sockaddr_in
全部或部分归零的要求。
请注意,sockaddr_in
used to的定义需要sin_zero
字段填充结构以使其与sockaddr
结构兼容:
sin_zero成员已从sockaddr_in结构中删除 公开集团基本决议bwg2001-004。
与sin_zero
一样,我们发现Windows和Linux之间存在差异。即使该字段已从官方定义中删除,Windows和Linux实现仍然包含它(因为“至少”的措辞并不明确违法)。
sin_zero
是否始终要求对Windows平台进行清零还不清楚,但在this blog post中,作者进行了一些挖掘并提出了以下内容:
在某些架构上,它不会导致任何不清除的问题 的sin_zero。但在其他架构上它可能会。它的要求 清除
sin_zero
的规范,因此如果您打算这样做必须这样做 你的代码现在和将来都没有bug。
对于“规范要求清除sin_zero
”的部分,我只能找到以下Windows documentation (for Winsock Kernel)似乎支持该声明:
WSK应用程序应该将此数组的内容设置为零。
但是,我找不到类似Linux的措辞。
总而言之,似乎在某些体系结构中,您需要将至少一个字段清零,而在其他体系结构中则不需要。我认为最好是保持安全并将所有事情归零。
答案 1 :(得分:0)
聚会晚了点-但是这里有一些相关的东西,我认为这是值得讨论的补充。理查德·史蒂文斯(Richard Stevens)的第3版“ Unix网络编程”中有以下内容:
“ ......绑定非通配符IPv4地址时,该成员必须为零(TCPv2的第731-732页)”
Stevens在这里提到“ TCPv2”-他在说的“成员”是sin_zero
。至少在bind
-ing的情况下,这似乎与您的问题的概况相符。请注意,他使用了必须一词。
此答案是否符合“官方文档”的条件……我留给您!但是,正如其他人所说的那样,不管它是否正式...肯定将memset
设为零(或在结构变量定义中使用= {0};
都是一个好主意)。这样,您不必担心...