正在将"sockaddr_in"清零.结构必要吗? [英] Is zeroing out the "sockaddr_in" structure necessary?
问题描述
在任何地方,我都会看到以下代码:
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套接字实现确实为sockaddr_in
定义了sin_zero
成员,但是他们总是说需要填充该成员,以将sockaddr_in
的大小与sockaddr
对齐.而且他们从不要求将任何特定内容放入其中.
是否有任何真实,证明的文档需要将该结构归零?
P.S.
在VTC之前,请将该问题作为与sockaddr_in
上有关memset
的多个SO问题之一相同的问题,请确保您所建议的问题与正式文档有任何链接,而不只是猜测初始化未使用的成员以防万一.
简短答案:
IEEE标准不需要它.
长(长)答案:
IEEE标准
1003.1 指定sockaddr_in
的定义为( Emphasis 我的):
标题应定义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
以前的定义需要一个sin_zero
字段来填充该结构,以使其与sockaddr
结构兼容:
sin_zero成员已按照如下方式从sockaddr_in结构中删除 开放小组基本决议bwg2001-004.
与sin_zero
一起,我们发现Windows和Linux之间存在差异.即使该字段已从官方定义中删除,但Windows和Linux实施仍然包括该字段(因为使用至少"一词并没有明显的非法性).
对于Windows平台,sin_zero
是否始终需要归零尚不清楚,但在 解决方案
Short answer:
The IEEE Standard doesn't require it.
Long(er) answer:
The IEEE Standard
1003.1 specifies that the definition of sockaddr_in
is (Emphasis mine):
The header shall define the sockaddr_in structure that includes at least the following members:
sa_family_t sin_family AF_INET.
in_port_t sin_port Port number.
struct in_addr sin_addr IP address.
Note that, unlike the definition for sockaddr_in6
, which specifies that it should be zeroed out:
The
sockaddr_in6
structure shall be set to zero by an application prior to using it, since implementations are free to have additional, implementation-defined fields insockaddr_in6
.
There is no similar wording for sockaddr_in
. However, such lack of wording gives platform implementors enough ambiguity to make their own requirements about zeroing out all or part of sockaddr_in
.
Note that the definition of sockaddr_in
used to require a sin_zero
field to pad out the structure to make it compatible with sockaddr
structures:
The sin_zero member was removed from the sockaddr_in structure as per The Open Group Base Resolution bwg2001-004.
And it's with sin_zero
we find a discrepancy between Windows and Linux. Even though the field was removed from the official definition, both Windows and Linux implementation still include it (because it's not explicitly illegal thanks to the wording "at least").
Whether sin_zero
always requires zeroing out or not for Windows platforms isn't clear, but in this blog post the writer did some digging and came up with the following:
On some architectures, it wont cause any problems not clearing sin_zero. But on other architectures it might. Its required by specification to clear
sin_zero
, so you must do this if you intend your code to be bug free for now and in the future.
For the part about "It's required by specification to clear sin_zero
", I could only find the following Windows documentation (for Winsock Kernel) appearing to support the claim:
A WSK application should set the contents of this array to zero.
However, I can find no similar wording for Linux.
So to conclude, it appears that in some architectures you need to zero out at least one field, while in others you don't. I think it's best to be safe and zero out everything.
这篇关于正在将"sockaddr_in"清零.结构必要吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!