18.4.1 查询主机名称

18.4.1  查询主机名称

查询主机名称是通过访问主机数据库实现的,服务器数据库接口函数在头文件netdb.h中定义。与此相关的函数有sethostbyaddr()gethostbyname()两个,它们的一般形式如下:

 

struct hostent *gethostbyaddr(const void *addr, size_t len, int type);

struct hostent *gethostbyname(const char *name);

 

函数的返回值是指向hostent结构的指针,该结构用于保存主机名称等信息,hostent结构的定义如下:

 

struct hostent {

   char *h_name;                     // 主机名

   char **h_aliases;                 // 别名列表

   int h_addrtype;                  // 地址类型

   int h_length;                // 地址的字节长度

   char **h_addr_list                // 地址列表

};

 

gethostbyaddr()是通过IP地址查询主机信息,gethostbyname()是通过主机名查询主机信息。如果在主机数据库中没有查到相关主机或地址的项,这些函数会返回一个空指针。

与服务及其关联的端口号有关的信息可以通过getservbyname()函数和getservbyport()函数查询,它们的一般形式如下:

 

struct servent *getservbyname(const char *name, const char *proto);

struct servent *getservbyport(int port, const char *proto);

 

其中,proto参数指定了用来连接到该项服务的协议,SOCK_STREAM类型的TCP连接对应的是tcpUDP连接对应的是udp。函数的返回值是servent结构指针,该结构的定义如下:

 

struct servent {

   char *s_name;             // 服务名

   char **s_aliases;         // 服务别名列表

   int s_port;              // 端口号

   char *s_proto;            // 协议类型

};

 

如果需要将地址信息转换为四分十进制法表示,可使用inet_ntoa()函数来完成。该函数被包含在头文件“arpa/inet.h”中,它的一般形式是:

 

char *inet_ntoa(struct in_addr in);

 

如果执行成功,它将返回一个指向四分十进制法表示地址的字符串的指针,否则返回–1。查询当前主机的主机名的函数是gethostname(),该函数的一般形式是:

 

int gethostname(char *name, int namelength);

 

如果执行成功,*name参数所指向的内存空间将被写入主机名,namelength参数限定了*name参数所指向内存空间的长度。如果主机名太长,会被截短到namelength限定的长度。函数执行成功时返回0,否则返回–1。下面用一个示例说明查询主机名称操作的方法:

 

#include <sys/socket.h>                     // 包含套接字相关函数

#include <netinet/in.h>                     // 包含AF_INET相关结构

#include <netdb.h>                          // 包含读取主机信息的相关函数

#include <stdio.h>

#include <unistd.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, "找不到主机: %s/n", host);

      return 1;

   }

   servinfo = getservbyname("daytime", "tcp");      // 获得服务信息

   if (!servinfo) {

      fprintf(stderr, "daytime服务/n");

      return 1;

   }

   printf("daytime服务端口是:%d/n", ntohs(servinfo -> s_port)); 

                                                    // 输出端口信息

   sockfd = socket(AF_INET, SOCK_STREAM, 0);    // 建立套接字

   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("获得数据出错");

      return 1;

   }

   result = read(sockfd, buffer, sizeof(buffer));   // 接收数据

   buffer[result] = '/0';

   printf("读取%d字节:%s", result, buffer);         // 输出数据

   close(sockfd);                                   // 关闭连接

   return 0;

}

 

运行程序时,将一个UNIX服务器地址作为该程序的运行参数。daytime服务的端口号是通过网络数据库函数getserverbyname()确定的,这个函数返回的是关于网络服务方面的资料,它们和主机资料差不多。程序会先尝试连接指定主机信息数据库里的地址,如果成功就读取daytime服务返回的信息,该信息是一个表示UNIX时间和日期的字符串。如果测试平台是Linux桌面操作系统,修改“/etc/xinetd.d/daytime”文件,将此文件中两个disable的值由yes改为no,再重启计算机即可运行daytime服务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值