一 主机数据库函数
#include <netdb.h> struct hostent *gethostbyaddr( const void *addr, //地址
size_t len, //长度
int type //类型
); struct hostent *gethostbyname( const char *name);
这些函数返回的结构中至少包含以下几个成员
struct hostent{ char *h_name; // 主机名称 char **h_aliases; // 别名列表 int h_addrtype; // 地址类型 int h_length; // 地址长度 char **h_addr_list; // 地址列表 };
如果想获得某台计算机的主机数据库信息,可以调用gethostbyname函数并且将结果打印出来,注意,要把返回的地址列表转换为正确的地址类型,并用函数inet_ntoa将它们从网络字节序转换为可打印的字符串
#include <arpa/inet.h> char *inet_ntoa( struct in_addr in );
函数作用:将一个因特网主机地址转换为一个点分四元组格式的字符串
#include <unistd.h> int gethostname( char *name, int namelength);
函数作用:将当前主机的名字写入name指向的字符串中。主机名为null结尾。参数namelength指定了字符串name的长度,如果返回的主机名太长,它就会被截断
例子:
#include <stdio.h> #include <arpa/inet.h> #include <stdlib.h> #include <netdb.h> #include <netinet/ in .h> int main( int argc, char * argv[]){ char *host,**names,** addrs; struct hostent * hostinfo; // 把host变量设置为getname程序所提供的命令行参数,或默认设置为用户主机的主机名 if (argc== 1 ){ char myname[ 256 ]; gethostname(myname, 255 ); host = myname; } else { host =argv[ 1 ]; } // 调用gethostbyname,如果未找到相应的信息就报告一条错误 hostinfo= gethostbyname(host); if (! hostinfo){ sprintf(stderr, " Cannot get info for host:%s\n " ,host); exit( 1 ); } // 显示主机名和它可能有的所有别名 printf( " result for host:%s\n " ,host); printf( " Name:%s\n " ,hostinfo-> h_name); printf( " Aliases: " ); names =hostinfo-> h_aliases; while (* names){ printf( " %s " ,* names); names ++ ; } printf( " \n " ); if (hostinfo->h_addrtype!= AF_INET){ fprintf(stderr, " not an IP host!\n " ); exit( 1 ); } addrs =hostinfo-> h_addr_list; while (* addrs){ printf( " %s " ,inet_ntoa(*( struct in_addr*)* addrs)); addrs ++ ; } printf( " \n " ); exit( 0 ); }
二 服务信息函数
#include <netdb.h> struct servent *getservbyname( const char *name, //服务名称
const char * proto //指定用于连接该服务的协议,它的取值是tcp(用于SOCK_SREAM类型的TCP连接)和udp(用于SOCK_DGRAM类型的UPD数据报)
); struct servent *getservbyport( int port, //端口号
const char *proto
);
结构servent至少包含一下几个成员
struct servent{ char *s_name; // 服务名称 char **s_aliases; // 别名列表 int s_port; // IP端口号 char *s_proto; // 服务类型 };
例子:
#include <sys/socket.h> #include <netinet/ in .h> #include <netdb.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main( int argc, char * argv[]){ char * host; int sockfd; int len,result; struct sockaddr_in address; struct hostent * hostinfo; struct servent * servinfo; char buffer[ 128 ]; if (argc== 1 ){ host = " localhost " ; } else { host =argv[ 1 ]; } // 查找主机的地址,如果找不到,就报告一条错误 hostinfo= gethostbyname(host); if (! hostinfo){ fprintf(stderr, " no host:%s\n " ,host); exit( 1 ); } // 检查主机上是否有daytime服务 servinfo=getservbyname( " daytime " , " tcp " ); if (! servinfo){ fprintf(stderr, " no daytime service\n " ); exit( 1 ); } printf( " daytime port is %d\n " ,ntohs(servinfo-> s_port)); // 创建一个套接字 sockfd=socket(AF_INET,SOCK_STREAM, 0 ); // 构造connect调用要使用的地址 address.sin_family= AF_INET; address.sin_port =servinfo-> s_port; address.sin_addr =*( struct in_addr*)*hostinfo-> h_addr_list; len = sizeof (address); // 然后建立连接并取得有关信息 result=connect(sockfd,( struct sockaddr *)& address,len); if (result==- 1 ){ perror( " oops:getdate " ); exit( 1 ); } result =read(sockfd,buffer, sizeof (buffer)); buffer[result] = ' \0 ' ; printf( " read %d bytes:%s " ,result,buffer); close(sockfd); exit( 0 ); }