名字与地址转换
gethostbyname/gethostbyaddr
均用于IPv4中, 第一个通过域名查ip地址, 第二个通过ip地址反向查询域名.
不过需要注意的反向查询需要本地有反射解析服务, 或者说本地的etc/hosts文件中有相应的记录
#include <netdb.h>
struct hostent *gethostbyname(const char *hostname);
struct hostent *gethostbyaddr(const char *addr,socklen_t len,int family);
struct hostent{
char *h_name; //域名
char **h_aliases; //别名
int h_addrtype; //AF_INET
int h_length; // 4
char **h_addr_list; //域名对应的IPv4地址链
}
gethostbyname的参数是域名的字符串
gethostbyaddr的第一个参数是IPv4地址的二进制字符串
#include "unp.h"
#include <netdb.h>
int main(int argc, char *argv[])
{
char *ptr,**pptr;
char str[INET_ADDRSTRLEN];
struct hostent *hptr;
while(--argc > 0){
ptr = *++argv;
if((hptr=gethostbyname(ptr)) == NULL){
printf("gethostbyname error for host: %s: %s",
ptr,hstrerror(h_errno));
continue;
}
printf("official hostname: %s\n",hptr->h_name);
for(pptr=hptr->h_aliases;*pptr != NULL;pptr++)
printf("\talias: %s\n",*pptr);
switch(hptr->h_addrtype){
case AF_INET:
pptr=hptr->h_addr_list;
for(;*pptr != NULL;pptr++)
printf("\taddress: %s\n",inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str)));
break;
default:
printf("unknown address type\n");
break;
}
}
return 0;
}
#include "unp.h"
#include <netdb.h>
int main(int argc, char *argv[])
{
char *ptr,**pptr;
char str[INET_ADDRSTRLEN];
struct hostent *hptr;
struct in_addr *addr;
struct sockaddr_in saddr;
while(--argc > 0){
ptr = *++argv;
if(!inet_aton(ptr,&saddr.sin_addr))
err_quit("inet_aton error");
if((hptr=gethostbyaddr((void *)&saddr.sin_addr,sizeof(struct in_addr),AF_INET)) == NULL)
err_quit("gethostbyaddr error:%s %s ",ptr, hstrerror(h_errno) );
printf("official hostname: %s\n",hptr->h_name);
for(pptr=hptr->h_aliases;*pptr!=NULL;pptr++)
printf("\talias: %s\n",*pptr);
switch(hptr->h_addrtype){
case AF_INET:
pptr=hptr->h_addr_list;
for(;*pptr != NULL;pptr++)
printf("\taddress:%s\n",
inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str)));
break;
default:
puts("unknown address type\n");
break;
}
}
return 0;
}
getservbyname/getservbyport
大致就是输入http输出80; 输入21输出ftp
#include <netdb.h>
struct servent *getservbyname(const char *servname, const char *protoname);
struct servent *getservbyport(int port, const char *protoname);
struct servent{
char *s_name; /* http,ftp... */
char **s_aliases; /* 别名 */
int s_port; /* 端口号 */
char *s_proto; /* tcp 或 udp */
}
getservbyport中的port参数需要网络字节序
#include "unp.h"
#include <netdb.h>
int main(int argc, char *argv[])
{
struct servent *ent;
if(argc < 2)
err_quit("usage: ./port2name [port]");
if((ent=getservbyport(htons(atoi(argv[1])),"tcp")) == NULL)
err_quit("getservent error");
printf("official name: %s\n",ent->s_name);
printf("port %d\n",ntohs(ent->s_port));
return 0;
}
#include "unp.h"
#include <netdb.h>
int main(int argc, char *argv[])
{
struct servent *ent;
if(argc < 2)
err_quit("usage: ./name2port [service_name]");
if((ent=getservbyname(argv[1],"tcp")) == NULL)
err_quit("getservent error");
printf("official name: %s\n",ent->s_name);
printf("port %d\n",ntohs(ent->s_port));
return 0;
}