我只是想了解getaddrinfo()的行为。
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
产生的IP(v4 / v6)解决了(每个)struct addrinfo中保存的数据。
struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
};
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
如果结果之一是IPv6地址(16字节),如何将其保存在ai_addr中,该ai_addr的类型为sockaddr,其大小为< IPv6地址。
我的问题是,我正在将ai_addr类型转换为sockaddr_storage
(struct sockaddr_storage *)(res->ai_addr)
结束gcc警告:
警告:强制转换会增加目标类型所需的对齐
将sockaddr强制转换为sockaddr_storage的正确方法是什么?
几个答案后更新:
关于gcc警告的问题:
> warning: cast increases required alignment of target type
并通过以下方式解决:
(struct sockaddr_storage *)(void *)(res->ai_addr)
答案 0 :(得分:3)
ai_addr
只是一个指针。取决于ai_family
,ai_addr
背后的实际结构不同:
ai_family
是AF_INET
,它实际上是指向sockaddr_in
结构的指针。 ai_family
是AF_INET6
,则它是指向sockaddr_in6
结构的指针。由于sockaddr_in
,sockaddr_in6
和sockaddr_storage
(http://www.beej.us/guide/bgnet/output/html/multipage/sockaddr_inman.html)的结构,您可以根据ai_family
将指针强制转换为实际结构如上所述。
答案 1 :(得分:0)
您应该使用sockaddr_storage作为套接字类型,因为它对于IPv4和IPv6都足够大并且可以转换为sockaddr
struct sockaddr_storage {
sa_family_t ss_family; // address family
// all this is padding, implementation specific, ignore it:
char __ss_pad1[_SS_PAD1SIZE];
int64_t __ss_align;
char __ss_pad2[_SS_PAD2SIZE];
};