我们在winsock编程中常常会向指定url地址进行连接,但是这个必须通过url后面对应的ip地址实现。在获取url的ip的时候,我们使用gethostbyname得到hostent指针,然后把hostent指针转换成in_addr结构,因为sockaddr_in的结构如下:
struct sockaddr_in {
short int sin_family; /* Address family */
unsigned short int sin_port; /* Port number */
struct sin_addr; /* Internet address */
unsigned char sin_zero[8]; /* Same size as struct sockaddr */
};
这个in_addr结构可以直接赋值给sockaddr_in结构体的sin_addr。这样,我们的winsock地址就实现啦!下面对这个具体实现进行分析:
首先,我们了解ip地址的本质。按照Tcp/IP协议规定,IP地址用二进制表示,每个IP地址长32bit,也就是4个字节。例如,一个采用二进制形式表示的IP地址是“00001010000000000000000000000001” ,如果用IP地址表示,他就是“10.0.0.1” ,后面的好记多啦!我们称后面这种为“点分十进制表示法” 。
我们在gethostbyname中取得的host结构如下
struct hostent {
char *h_name; h_name – 地址的正式名称。
char **h_aliases; 空字节-地址的预备名称的指针。
int h_addrtype; h_addrtype –地址类型; 通常是AF_INET。
int h_length; 地址的比特长度
char **h_addr_list; 零字节-主机网络地址指针。网络字节顺序。
};
#define h_addr h_addr_list中的第一地址。
在这个里面,h_addr_list就是IP地址的二进制表示,同时in_addr的结构
其实,我们存储在内存中的in_addr也是以二进制表示的IP地址,那么,我们从hostent到in_addr结构,就可以简单使用memmove(&in_addr,hostetn->h_addr,hostent->h_length);
怎么样,这样转换很简单吧,搞懂原理,这个过程实现很高效哦,其实了,还有跟高效的,不是么?
Memmove(&(sockaddr_in->sin_addr),hosten->h_addr,hostent->h_length);
是不是很简单呢?