一. gethostbyname
1. 获取主机名
-
在/usr/include/netdb.h中
-
struct hostent
-
{
-
char *h_name; //主机的规范名:参见下面的sina.com
-
char **h_aliases; //主机的别名,可能有很多个所以这儿是个list
-
int h_addrtype; //ip地址类型,AF_INET(IPv4),AF_INET6(IPv6)
-
int h_length; //ip地址长度: 为4
-
char **h_addr_list; //主机的ip地址:网络字节序存储的
-
};
例如地址为:202.102.75.147
网络字节序是:0xca 0x66 0x4b 0x93
2.源码
-
cong@msi:/work/test/tcpip/19echo$ cat name.c
-
#include "utils.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)
-
{
-
dbmsg("gethostbyname error");
-
continue;
-
}
-
dbmsg("official hostname: %s", hptr->h_name);
-
for(pptr=hptr->h_aliases; *pptr!=NULL; pptr++)
-
dbmsg("alias:%s", *pptr);
-
switch( hptr->h_addrtype)
-
{
-
case AF_INET:
-
pptr = hptr->h_addr_list;
-
for(; *pptr!=NULL; pptr++)
-
dbmsg("address:%s", inet_ntop(hptr->h_addrtype,*pptr,str, sizeof(str)));
-
break;
-
}
-
}
-
return EXIT_SUCCESS;
-
}
utils.h
-
cong@msi:/work/test/tcpip/19echo$ cat utils.h
-
#ifndef UTILS_H__
-
#define UTILS_H__
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <sys/types.h> /* See NOTES */
-
#include <sys/socket.h>
-
#include <netinet/in.h>
-
#include <arpa/inet.h>
-
#include <time.h>
-
#include <string.h>
-
#include <errno.h>
-
#include <signal.h>
-
#include <netdb.h>
-
-
#define MAXLINE 1024
-
-
#define LISTENQ 10
-
#define dbmsg(fmt, args ...) printf("%s:%s[%d]: "fmt"\n", __FILE__,__FUNCTION__, __LINE__,##args)
-
#define max(a,b) ((a) > (b) ? (a) : (b))
-
-
#endif
3.运行结果
-
cong@msi:/work/test/tcpip/19echo$ ./name www.baidu.com
-
name.c:main[16]: official hostname: www.a.shifen.com
-
name.c:main[18]: alias:www.baidu.com
-
name.c:main[24]: address:180.97.33.108
-
name.c:main[24]: address:180.97.33.107
-
-
cong@msi:/work/test/tcpip/19echo$ ./name www.sina.com
-
name.c:main[16]: official hostname: newsnj.sina.com.cn //看到没,主机的规范名与输入的是不一样的
-
name.c:main[18]: alias:www.sina.com
-
name.c:main[18]: alias:us.sina.com.cn
-
name.c:main[18]: alias:news.sina.com.cn
-
name.c:main[18]: alias:jupiter.sina.com.cn
-
name.c:main[24]: address:202.102.75.147
hostname.rar (下载后改名为hostname.tar.gz)
二. gethostbyaddr
2.1 查看gethostbyaddr的man_page
-
a.原型:
-
#include <sys/socket.h> /* for AF_INET */
-
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type);
-
b.参数说明
-
type: The gethostbyaddr() valid address types are AF_INET and AF_INET6.
-
addr: The host address argument is a pointer to a struct of a type depending on the address type, for example a struct in_addr * (probably obtained via a call to inet_addr(3)) for address type AF_INET. (addr参数可以通过net_addr()来得到)
2.2 代码
-
cong@msi:/work/test/tcpip/ch11/hostaddr$ cat addr.c
-
#include "utils.h"
-
-
int main ( int argc, char *argv[] )
-
{
-
struct hostent *hptr;
-
long addr;
-
if (argc != 2) {
-
fprintf(stderr, "usage: %s i.p.addres", argv[0]);
-
exit(1);
-
}
-
addr = inet_addr(argv[1]);
-
hptr = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
-
if(NULL == hptr)
-
{
-
dbmsg("host %s not found", argv[1]);
-
exit(1);
-
}
-
dbmsg("Hostname:%s", hptr->h_name);
-
while (hptr->h_aliases[0])
-
dbmsg("Aliases:%s", *hptr->h_aliases++);
-
while (hptr->h_addr_list[0])
-
dbmsg("Addresses:%s", inet_ntoa(*(struct in_addr *) * hptr->h_addr_list++));
-
return EXIT_SUCCESS;
-
}
2.3 运行结果
-
cong@msi:/work/test/tcpip/ch11/hostaddr$ ./addr 8.8.8.8
-
addr.c:main[19]: Hostname:google-public-dns-a.google.com
-
addr.c:main[23]: Addresses:8.8.8.8
hostaddr.rar (下载后改名为hostaddr.tar.gz)
三. gethostbyname
3.1 获取主机的服务
-
#include
-
struct servent
-
{
-
char *s_name; //表示服务的名称
-
char **s_aliases; //服务的别名链表
-
int s_port; //端口号
-
char *s_proto; //服务的协议
-
};
也可在以/etc/services中查看
3.2 代码
-
cong@msi:/work/test/tcpip/ch11/servname$ cat servname.c
-
#include "utils.h"
-
-
int main ( int argc, char *argv[] )
-
{
-
struct servent * sptr;
-
if (argc != 3) {
-
fprintf(stderr, "usage: %s i.p.addres", argv[0]);
-
exit(1);
-
}
-
sptr = getservbyname(argv[1], argv[2]);
-
if(NULL == sptr)
-
{
-
dbmsg("%s:%s not found",argv[1], argv[2]);
-
exit(0);
-
}
-
dbmsg("name=%s, port=%d, protocal=%s",
-
sptr->s_name, ntohs(sptr->s_port), sptr->s_proto);
-
-
return EXIT_SUCCESS;
-
}
3.2 运行结果
-
cong@msi:/work/test/tcpip/ch11/servname$ ./servname domain udp
-
servname.c:main[17]: name=domain, port=53, protocal=udp
-
cong@msi:/work/test/tcpip/ch11/servname$ ./servname ftp tcp
-
servname.c:main[17]: name=ftp, port=21, protocal=tcp
-
cong@msi:/work/test/tcpip/ch11/servname$ ./servname ftp udp
-
servname.c:main[13]: ftp:udp not found
servname.rar (下载后改名为servname.tar.gz)
四. getservbyport
4.1 代码
-
cong@msi:/work/test/tcpip/ch11/servport$ cat servport.c
-
#include "utils.h"
-
-
int main ( int argc, char *argv[] )
-
{
-
struct servent * sptr;
-
int port;
-
if (argc != 3) {
-
fprintf(stderr, "usage: %s i.p.addres", argv[0]);
-
exit(1);
-
}
-
port = atoi(argv[1]); //第1个参数是int型
-
sptr = getservbyport(htons(port), argv[2]); //并一定要转为网络字节序
-
if(NULL == sptr)
-
{
-
dbmsg("%s:%s not found",argv[1], argv[2]);
-
exit(0);
-
}
-
dbmsg("name=%s, port=%d, protocal=%s",
-
sptr->s_name, ntohs(sptr->s_port), sptr->s_proto);
-
-
return EXIT_SUCCESS;
-
}
4.2 运行结果
-
cong@msi:/work/test/tcpip/ch11/servport$ ./servport 53 udp
-
servport.c:main[19]: name=domain, port=53, protocal=udp
-
cong@msi:/work/test/tcpip/ch11/servport$ ./servport 21 tcp
-
servport.c:main[19]: name=ftp, port=21, protocal=tcp
-
cong@msi:/work/test/tcpip/ch11/servport$ ./servport 21 udp
-
servport.c:main[19]: name=fsp, port=21, protocal=udp
servport.rar (下载后改名为servport.tar.gz)
五. getaddrinfo
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
阅读(948) | 评论(0) | 转发(0) |