hostent:
数据结构:
struct hostent{
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
};
详细资料:
h_name -- 主机的正式名称;
h_aliases -- 空字节 - 主机的别名;
h_addrtype -- 主机 ip 地址类型; ipv4(AF_INET),ipv6(AF_INET6)
h_length -- 主机 ip 地址的比特长度;
h_addr_list -- 零字节 - 主机网络地址指针;网络字节序,所以要打印出的话要调用 inet_ntop()
批注:
使用这个东西,首先要包含 2 个头文件:
#include<netdb.h>
#include<sys/socket.h>
gethostbyname() 成功时返回一个指向结构体 hostent 指针,或者是个空 (NULL) 指针。
例子:
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
struct hostent *h;
if (argc != 2) { /* 检查命令行 */
fprintf(stderr,"usage: getip address");
exit(1);
}
if ((h=gethostbyname(argv[1])) == NULL) { /* 取得地址信息 */
herror("gethostbyname");
exit(1);
}
printf("Host name : %s ", h->h_name);
printf("IP Address : %s ",inet_ntoa(*((struct in_addr *)h->h_addr)));
return 0;
}
注意:在使用 gethostbyname() 时,不能用 perror() 打印错误信息(因为 errno 没有使用),应该调用 herror().
struct hostent *gethostbyname(const char*name);
这个函数的传入值是域名或者主机名,例如: “www.google.com” 等等。传出值是一个 hostent 的结构。如果函数调用失败,将返回 NULL 。
sockaddr 与 sockaddr_in:
数据结构:
struct sockaddr{
unsigned short sa_family;// 地址族, AF_xxx AF_INET 不涉及转序的问题
char sa_data[14];//14 字节的协议地址,网络字节序
} ;
此时: struct in_addr{
unsignedlong s_addr;
}
struct sockeaddr_in {
short int sin_family; // 地址族
unsigned short int sin_port; // 端口号
struct in_addr sin_addr; //Internet 地址
unsigned char sin_zero[8]; // 与 structsockaddr 一样的长度, 16 个字节
};
此时: 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_longS_addr;
}S_un;
};
inet_addr() 是将一个点分制的 IP 地址(如 192.168.0.1 )转换为上述结构中需要的 32 位 IP 地址( 0xC0A80001 )
通常的用法是:
socket sockfd;
struct hostent *he;
struct sockaddr_in my_addr;
if ((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1) {
perror("socket");
exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&(my_addr.sin_zero,8);//zero the rest of the struct
if (bind(sockfd, (struct sockaddr *)&my_addr,sizeof(structsockaddr)) == -1){
perror("bind");
exit(1);
}