sockaddr结构体 - (sys/socket.h)

6
我一整天都在阅读 sys/socket.h ,终于开始理解它了,现在开始使用它,但是我不确定为什么无法给 sockaddr 结构体的 sa_family 成员赋值。
规范中的 sockaddr 结构体:
struct sockaddr{
    sa_family_t   sa_family       address family
    char          sa_data[]       socket address (variable-length data)
};

数据类型:sa_family_t - 无符号整数类型(2-4个字节)

取值:

Name                Purpose                          Man page
       AF_UNIX, AF_LOCAL   Local communication              unix(7)
       AF_INET             IPv4 Internet protocols          ip(7)
       AF_INET6            IPv6 Internet protocols          ipv6(7)
       AF_IPX              IPX - Novell protocols
       AF_NETLINK          Kernel user interface device     netlink(7)
       AF_X25              ITU-T X.25 / ISO-8208 protocol   x25(7)
       AF_AX25             Amateur radio AX.25 protocol
       AF_ATMPVC           Access to raw ATM PVCs
       AF_APPLETALK        AppleTalk                        ddp(7)
       AF_PACKET           Low level packet interface       packet(7)
       AF_ALG              Interface to kernel crypto API

这有点令人困惑,因为这些值是char数据类型而不是unsigned int

简单测试:

#include<stdio.h>
#include<sys/socket.h> 

int main(void){
    struct sockaddr_in address;
    address.sin_family = AF_INET;
    printf("Socket Address Family: %s\n", address.sin_family);
    return 0;
}

错误:

address的存储大小未知

应该输出套接字地址族:AF_INET…我在这里缺少了什么?


1
printf("套接字地址族: %s\n", address.sin_family); 这没有意义。它不是一个字符串。 - David Schwartz
那正是我的观点...但我已经意识到它是一个与整数2相关联的宏常量...在socket.h源文件中。 - Jordan Davis
1个回答

5

我将 %s 改为 %d 以适应整数,现在输出为 2。但是,如果我查看 <netinet/in.h>,我并没有看到它与数字 2 相关联的地方? - Jordan Davis
1
我不是100%确定,但似乎尽管结构在<netinet/in.h>中声明,但AF_INET是一个宏常量,在socket.h中定义为2。以下是来自socket.h的代码:http://students.mimuw.edu.pl/SO/Linux/Kod/include/linux/socket.h.html - Paul92
是的,您就是那个人,是的,我只是在查看socket.h源文件。谢谢!谢谢! - Jordan Davis
1
@JordanDavis 实际上,sa_data 字段只存在于通用的 struct sockaddr 中。在 struct sockaddr_in 中,IP 地址位于 sin_addr 中,而端口位于 sin_port 中。这些字段的字节采用网络字节顺序(即大端序),因此您需要使用 htons()ntohs() 来处理端口,使用 htonl()ntohl() 来处理地址,以在网络字节顺序和主机字节顺序之间进行转换。 - dbush
@dbush 我会选择“通用”的默认struct sockaddr而不是sockaddr_in,那么在使用sa_data[]时,它是地址+端口的组合吗? - Jordan Davis
2
@JordanDavis 你不想这么做。除了 sa_family 字段外,struct sockaddr 是一个不透明的结构,在不同的机器上可能会有不同的布局。直接写入 sa_data 不具备可移植性。 - dbush

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