首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >sockaddr中的sa_data字段的用途是什么?

sockaddr中的sa_data字段的用途是什么?
EN

Stack Overflow用户
提问于 2015-09-17 15:34:29
回答 2查看 11.3K关注 0票数 7
代码语言:javascript
运行
复制
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

为addr参数传递的实际结构将取决于地址族。sockaddr结构被定义为类似于:

代码语言:javascript
运行
复制
struct sockaddr {
    sa_family_t sa_family;
    char        sa_data[14];
}

因此,对于IPv4地址(AF_INET),将传递的实际结构如下:

代码语言:javascript
运行
复制
/* Source http://linux.die.net/man/7/ip */

struct sockaddr_in {
    sa_family_t    sin_family; /* address family: AF_INET */
    in_port_t      sin_port;   /* port in network byte order */
    struct in_addr sin_addr;   /* internet address */
};

/* Internet address. */
struct in_addr {
    uint32_t       s_addr;     /* address in network byte order */
};

绑定代码是否读取sockaddr.sa_family值,然后根据找到的值将sockaddr结构转换为适当的结构,如sockaddr_in

为什么sa_data设置为14个字符?如果我没记错的话,sa_data字段只是一个有足够大的存储空间来容纳所有地址族类型的字段?据推测,最初的设计者预计14个字符将足够宽,以适应未来的所有类型。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-17 16:01:42

根据glibc manual的说法

sa_data的长度14本质上是任意的。

FreeBSD developers handbook提到了以下几点:

请注意sa_data字段声明的模糊性,就像14个字节的数组一样,注释提示可能超过14个字节。

套接字是一个非常强大的接口。虽然大多数人可能认为套接字只不过是Internet接口-现在大多数应用程序可能都在使用它-但套接字几乎可以用于任何类型的进程间通信,而Internet (或者更准确地说,IP)只是其中之一。

是的,sa_family字段用于识别如何处理传递的结构(该结构在绑定调用中强制转换为struct sockaddr* )。你也可以在FreeBSD developers handbook中阅读更多关于它是如何工作的内容。

实际上,存在“多态”(Sub)类型的sockaddr,其中sa_data包含超过16个字节,例如:

代码语言:javascript
运行
复制
struct sockaddr_un {
    sa_family_t sun_family;               /* AF_UNIX */
    char        sun_path[108];            /* pathname */
};
票数 10
EN

Stack Overflow用户

发布于 2015-09-17 16:15:47

sockaddr结构用作带标记的联合。通过读取sa_family字段,可以将其转换为适当形式的结构。

这14个字节是任意的。它的大小足以容纳IPv4地址,但不足以容纳IPv6地址。还有一个sockaddr_storage结构,它足够大,可以同时满足这两种情况。在SOCKADDR_STORAGE上阅读微软文档时,它有128字节,比IPv6所需的要大得多。检查一些Linux头文件,它看起来至少也有那么大。

作为参考,IPv6结构是:

代码语言:javascript
运行
复制
struct sockaddr_in6 {
    u_int16_t       sin6_family;   // address family, AF_INET6
    u_int16_t       sin6_port;     // port number, Network Byte Order
    u_int32_t       sin6_flowinfo; // IPv6 flow information
    struct in6_addr sin6_addr;     // IPv6 address
    u_int32_t       sin6_scope_id; // Scope ID
};

struct in6_addr {
    unsigned char   s6_addr[16];   // IPv6 address
};

正如您所看到的,16字节的s6_addr字段本身已经比14字节的sa_data字段大了。sa_family字段后的总大小为26字节。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32624847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档