sa_family_t是什么?

4

我正在跟随Beej的网络编程指南,并且我正在使用VC++ 2010,但是当我将结构体复制粘贴到我的程序中时,一些类型出现了不正确的标识符。例如:

u_int32_t 出现了这种情况,经过一些搜索,我发现这些是C语言约1999年的旧类型。我本可以只包含 stdint.h,但那就需要我记住它们的含义。相反,我使用标准的 int,它有32位长(4字节),对于其他64位长(8字节)的类型,我使用了 long long int

总之,我正在缩小到最后一个语法错误,并且它说 sa_family_t 是无效的标识符。我不知道它应该是什么,搜索也没有找到任何结果。这就是我的问题,我不知道我应该为该类型标识符指定什么。

还有一件事情困扰着我: char __ss_pad1[_SS_PAD1SIZE]; 这个 SS_PAD1SIZE 也显示为无效。


3
我使用了标准的“int”,它有32位长——但并非在每个平台上都是如此,这就是为什么存在uin32_t等类型的原因。 - user529758
你能否发布一些代码,以便我们可以看到 sa_family_t 是如何被使用的?此外,请注意,u_int32_t 是无符号类型,而 int 是有符号的。这可能会导致您的程序在后续中出现不良行为,具体取决于声明为 int 的变量如何被使用。 - HeatfanJohn
那些是来自于C语言1999年左右的旧类型。不,它们是1999年的新类型——请记住,C语言已经有40多年的历史了,在C语言中,1999年并不久远。 - Jonathan Wakely
1
u_int32_t 在 C 或 POSIX 中不是标准类型。uint32_t 是 C99 及其后续版本中的标准(但从技术上讲是可选)类型。请记住,一些 C 编译器(尤其是来自 Microsoft 的编译器)尚未付出太多努力来实现 C99;它们仍然基本上是 C89 编译器。 - Jonathan Leffler
我们两个都很老了,40年是很长的时间)。我能否得到一个答案,为什么我必须使用typedef?我猜想这是因为如果新代码使用旧类型,以后更容易更改事物。此外,“_SS_PAD1SIZE”是什么? - Johanne Irish
显示剩余2条评论
2个回答

8

sa_family_t应该是无符号整数。 Windows头文件不符合该标准。Winsock.h将sockaddr结构定义如下:

struct sockaddr {
        u_short sa_family;              /* address family */
        char    sa_data[14];            /* up to 14 bytes of direct address */
};

因此,为了编译您的代码,您需要自己定义sa_family_t。


“yourself” 的意思是 “你自己”,可能是作为 typedef u_short sa_family_t 使用的。 - Jonathan Leffler
1
不,现代编译器不会将int变成unsigned。如果没有unsigned关键字,int始终表示有符号整数。是的,您可以在所有出现sa_family_t的地方将其替换为unsigned int,但更容易且更可维护的方法是在一个地方typedef sa_family_t。 - Carey Gregory
哦,而“circa”意味着大约或关于一个近似的日期。它并不意味着旧。 - Carey Gregory
你永远不知道它可能会帮助谁,因为Windows的typedef不符合标准。 - Carey Gregory
2
Linux同样将sa_family_t定义为unsigned short。我不确定说Windows在这里是否符合规范。我理解的规范是允许使用任何无符号整数类型。 - Andrew Thaddeus Martin
显示剩余5条评论

1

如果有人查找在Linux下的sa_family_t;,它在这里定义:

https://github.com/torvalds/linux/blob/1a5304fecee523060f26e2778d9d8e33c0562df3/include/linux/socket.h#L28

typedef __kernel_sa_family_t    sa_family_t;

相应地,__kernel_sa_family_t 在这里被定义:

https://github.com/torvalds/linux/blob/1a5304fecee523060f26e2778d9d8e33c0562df3/include/uapi/linux/socket.h#L10

typedef unsigned short __kernel_sa_family_t;

最终,sa_family_t 是一个 unsigned short,即 2 个字节。这将整个 struct sockaddr 压缩为整齐的 16 字节:
struct sockaddr {
    sa_family_t sa_family;  // unsigned short
    char        sa_data[14];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接