有关gethostbyname()的不可重入

最近发现很多小伙伴在自学Linux网络编程这本书,中间可能会有许多不解的疑惑,书上有些地方讲解的也不是很透彻,恰巧之前选修过这门课,今天分享一个遇到的问题。

首先请看书的229页,8.4.4 函数gethostbyname不可重入的例子

先看下这段代码:

#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
	struct hostent *ht=NULL;
	
	char host[]="www.sina.com.cn";				/*查询sina的主机域名*/
	char host1[]="www.sohu.com";				/*查询sohu的主机域名*/
	char str[30];
	struct hostent *ht1=NULL, *ht2=NULL;
	
	ht1 = gethostbyname(host);					/*查询"www.sina.com.cn"*/
	ht2 = gethostbyname(host1);					/*查询"www.sohu.com"*/
	int j = 0; 	
	for(j = 0;j<2;j++){
		if(j == 0)
			ht = ht1;								/*sina*/
		else
			ht =ht2;								/*sohu*/
		
		if(ht){
			int i = 0;
			printf("get the host:%s addr\n",host);			/*原始域名*/
			printf("name:%s\n",ht->h_name);				/*名称*/
			
			/*协议族AF_INET为IPv4或者AF_INET6为IPv6*/
			printf("type:%s\n",ht->h_addrtype==AF_INET?"AF_INET":"AF_INET6"); 		
			
			printf("legnth:%d\n",ht->h_length);			/*IP地址的长度*/
			/*打印IP地址*/
			for(i=0;;i++){
				if(ht->h_addr_list[i] != NULL){	/*不是IP地址数组的结尾*/
					printf("IP:%s\n",inet_ntop(ht->h_addrtype,ht->h_addr_list[i],str,30));							/*打印IP地址*/
				}	else{							/*达到结尾*/
					break;							/*退出for循环*/
				}
			}
			
			/*打印域名地址*/
			for(i=0;;i++){/*循环*/
				if(ht->h_aliases[i] != NULL){		/*没有到达域名数组的结尾*/
					printf("alias %d:%s\n",i,ht->h_aliases[i]);															/*打印域名*/
				}	else{							/*结尾*/
					break;							/*退出循环*/
				}
			}
		}
	}
	return 0;
}

这是这段代码的运行结果,其中第二行的运行结果是我的朋友问我最不能理解的:为什么ht的h_name输出结果是sohu而不是sina。

这就涉及到gethostbyname的函数处理方式,只需要了解一下几点:

第一:gethostbyname处理数据时返回的结果是存储在一个静态结构体变量中的,静态变量大家都懂,作为本地的一个全局变量,只初始化一次,也就是说,下次对这个变量进行操作时,是基于这次的结果来操作的

第二:ht1和ht2这个结构体指针在运行gethostbyname这个函数后指向的是同一个地址(即上面gethostbyname存储返回结果的变量地址)(大家可以在编译器里分部执行查看变量值的变化)

(表达可能不是很准确,大家可以理解我的意思即可或提出意见)

了解了这两点后,我们就可以知道,(14和15行)在第一次gethostbyname运行完之后,存储返回结果的变量的值存储的是原始域名host的域名(即www.sina.com.cn),此时ht1也指向这个存储这个变量的地址,但在第二次运行完之后,这个值已经变为了(www.sohu.com),而且此时ht1和ht2指向的地址都是这个结果的地址,所以第二行输出结果时即使此时ht赋值为ht1,(25和26行)结果仍是www.sohu.com,大家可以分享一下自己的看法或提出意见。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值