正在将"sockaddr_in"清零.结构必要吗? [英] Is zeroing out the "sockaddr_in" structure necessary?

查看:201
本文介绍了正在将"sockaddr_in"清零.结构必要吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在任何地方,我都会看到以下代码:

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 in sockaddr_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆