在网络中,主机都是用IP地址标示的;但是,出于很多理由,我们应该使用名字,而非纯数字:名字比较好记,数值地址可以变动但名字可以不变(如域名),随着往IPV6上转移,地址变得很长,数值书写容易出错等等。本文示例Linux几个处理名字与地址转换的函数的使用:
-
#include <netdb.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <netinet/in.h>
-
#include <getopt.h>
-
-
struct option g_opts[] = {
-
{"host", required_argument, NULL, 'h'},
-
{"server", required_argument, NULL, 's'},
-
{"protocol", required_argument, NULL, 'p'},
-
{"help", no_argument, NULL, 'H'}
-
};
-
-
/* struct hostent
-
{
-
char *h_name;
-
char **h_aliases;
-
int h_addrtype;
-
int h_length;
-
char **h_addr_list;
-
#define h_addr h_addr_list[0]
-
};
-
*/
-
-
/*
-
struct servent {
-
char *s_name; //official service name
-
char **s_aliases; //alias list
-
int s_port; //port number, network-byte order
-
char *s_proto; // protocol to use
-
*/
-
void showUsage()
-
{
-
printf("Usage:\n\tidns -h [ipstr/hostname]\n\t -s [servname/servport] -g [protocol]\n");
-
}
-
-
static void printServent(struct servent *sptr)
-
{
-
char **pptr;
-
-
printf("Server name: %s\n", sptr->s_name);
-
-
pptr = sptr->s_aliases;
-
while (pptr && *pptr != NULL)
-
{
-
printf("\taliases: %s\n", *pptr);
-
pptr++;
-
}
-
-
printf("\tport: %d\n", ntohs(sptr->s_port));
-
printf("\tproto: %s\n", sptr->s_proto);
-
}
-
-
static void printHostent(struct hostent *hptr)
-
{
-
char str[33] = { 0, };
-
char **pptr;
-
-
if (NULL == hptr)
-
return;
-
-
printf("Official hostname:%s\n", hptr->h_name);
-
-
for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
-
printf("alias:%s\n", *pptr);
-
-
switch (hptr->h_addrtype)
-
{
-
case AF_INET:
-
case AF_INET6:
-
pptr = hptr->h_addr_list;
-
for (; pptr && *pptr != NULL; pptr++)
-
printf("address: %s\n", inet_ntop(hptr->h_addrtype, *pptr, str, 32));
-
break;
-
default:
-
printf("Unknow address type\n");
-
break;
-
}
-
-
}
-
-
static void printHerror(int pError)
-
{
-
switch (pError)
-
{
-
case HOST_NOT_FOUND:
-
printf("host not found!\n");
-
break;
-
// case NO_ADDRESS:
-
// case NO_DATA:printf("112\n");break;
-
case NO_RECOVERY:
-
printf("no recovery!\n");
-
break;
-
case TRY_AGAIN:
-
printf("try again\n");
-
break;
-
default:
-
printf("unknow error type:%d\n", pError);
-
return;
-
}
-
}
-
-
void iGethostbyname_common(char *name)
-
{
-
struct addrinfo *answer, hint, *curr;
-
char ipstr[16];
-
int ret;
-
-
memset(&hint, 0, sizeof(hint));
-
hint.ai_flags = AI_CANONNAME;
-
-
ret = getaddrinfo(name, NULL, &hint, &answer);
-
if (ret != 0)
-
{
-
fprintf(stderr, "getaddrinfo fail: %s\n", gai_strerror(ret));
-
exit(1);
-
}
-
-
for (curr = answer; curr != NULL; curr = curr->ai_next)
-
{
-
printf("Host name: %s\n", curr->ai_canonname == NULL ? "" : curr->ai_canonname);
-
-
inet_ntop(AF_INET, &(((struct sockaddr_in *)(curr->ai_addr))->sin_addr), ipstr, 16);
-
printf("Addr: %s\n", ipstr);
-
}
-
-
freeaddrinfo(answer);
-
}
-
-
void iGethostbyname_ipv4(char *name)
-
{
-
struct hostent *hptr;
-
if ((hptr = gethostbyname(name)) == NULL)
-
{
-
printf("gethostbyname fail for host:%s\n", name);
-
return;
-
}
-
printHostent(hptr);
-
}
-
-
void iGethostbyaddr_ipv4(char *addr)
-
{
-
struct hostent *hptr;
-
in_addr_t nip;
-
int tryTimes = 3;
-
-
nip = inet_addr(addr);
-
-
L_TRY_AGAIN:
-
if ((hptr = gethostbyaddr(&nip, 4, AF_INET)) == NULL)
-
{
-
if (h_errno == TRY_AGAIN && tryTimes > 0)
-
{
-
tryTimes--;
-
goto L_TRY_AGAIN;
-
}
-
-
printf("Fail to get host by addr<%s>: ", addr);
-
printHerror(h_errno);
-
return;
-
}
-
printHostent(hptr);
-
}
-
-
void iGetservbyname(char *name, char *proto)
-
{
-
struct servent *sptr;
-
-
if ((sptr = getservbyname(name, proto)) == NULL)
-
{
-
printf("Can NOT find server with name:%s and protocol:%s\n", name, proto);
-
return;
-
}
-
-
printServent(sptr);
-
-
}
-
-
void iGetservbyport(int port, char *proto)
-
{
-
struct servent *sptr;
-
-
if ((sptr = getservbyport(htons(port), proto)) == NULL)
-
{
-
printf("Can NOT find server with port:%d and protocol:%s\n", port, proto);
-
return;
-
}
-
printServent(sptr);
-
}
-
-
char g_buf[64] = { 0, };
-
char g_proto[16] = { 0, };
-
-
int main(int argc, char **argv)
-
{
-
int opt;
-
int cmdType = 0;
-
-
int temp = 0;
-
-
if (argc < 2)
-
{
-
showUsage();
-
return 0;
-
}
-
-
while ((opt = getopt_long(argc, argv, "s:h:p:", g_opts, NULL)) != -1)
-
{
-
switch (opt)
-
{
-
case 's':
-
strcpy(g_buf, optarg);
-
cmdType = 1;
-
break;
-
case 'h':
-
strcpy(g_buf, optarg);
-
cmdType = 2;
-
break;
-
case 'p':
-
strcpy(g_proto, optarg);
-
break;
-
case 'H':
-
showUsage();
-
break;
-
default:
-
showUsage();
-
return;
-
}
-
}
-
-
if (cmdType == 2 && (inet_addr(g_buf)) == INADDR_NONE)
-
{
-
iGethostbyname_ipv4(g_buf);
-
}
-
else if (cmdType == 2)
-
{
-
iGethostbyaddr_ipv4(g_buf);
-
}
-
else if (cmdType == 1)
-
{
-
temp = atoi(g_buf);
-
if (temp > 0)
-
iGetservbyport(temp, g_proto);
-
else
-
iGetservbyname(g_buf, g_proto);
-
}
-
else
-
showUsage();
-
-
return 0;
-
}
阅读(2711) | 评论(0) | 转发(0) |