我需要将放置在structure中的套接字地址转换sockaddr
为structure in_addr
。我试图了解IP如何存储在这些结构中:
struct sockaddr {
u_short sa_family; /* address family */
char sa_data[14]; /* up to 14 bytes of direct address */
};
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
我陷入了疑问,如何127.0.0.1
存储为14个字符sa_data
。将sockaddr转换为in_addr的最佳方法是什么?
sockaddr
是通用结构,由不同类型的套接字共享。对于TCP / IP套接字,此结构变为sockaddr_in
(IPv4)或sockaddr_in6
(IPv6)。对于unix套接字,它变为sockaddr_un
。
理想情况下,您将使用sockaddr_in
代替sockaddr
。
但是给定sockaddr
,要从中提取IP地址,您可以这样做:
sockaddr foo;
in_addr ip_address = ((sockaddr_in)foo).sin_addr;
or
in_addr_t ip_address = ((sockaddr_in)foo).sin_addr.s_addr;
如果您向里看,sockaddr_in
您将看到的前2个字节sa_data
是端口号。接下来的4个字节是IP地址。
PS:请注意,IP地址是以网络字节顺序存储的,因此您可能需要使用ntohl
(网络到主机)和htonl
(主机到网络)转换成主机字节顺序或从主机字节顺序转换。
更新
对于IPv6,情况类似:
sockaddr foo;
in_addr6 ip_address = ((sockaddr_in6)foo).sin6_addr;
访问单个字节,使用ip_address[0]
... ip_address[15]
。
在sockaddr_in6
结构内部,sa_data
端口的前2个字节是端口号,后4个字节是流信息,其后的16个字节是IPv6地址。
警示[,然而,sockaddr_in6
是更大的比sockaddr
,所以从铸造时sockaddr
至sockaddr_in6
,确保该地址的确是通过检查地址族IPv6地址foo.sa_family == AF_INET6
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句