查询主机名对应的IP地址-C语言

这篇博客详细介绍了如何使用C语言在Windows环境下,通过动态链接库WS2_32.dll来获取主机名及其对应的IP地址。首先进行WSAStartup初始化,然后根据传入的主机名(可能是本地主机或指定域名)使用gethostname或gethostbyname函数进行解析。程序展示了如何处理可能的错误,并输出查询结果,包括主机名、别名、地址类型、地址长度以及IP地址列表。
摘要由CSDN通过智能技术生成

查询主机名对应的IP地址

操作步骤:

  1. 编译:gcc getip.c -lws2_32 -o getip.exe
  2. 运行:getip 主机名
  3. 结果:
		主机名 域名:DESKTOP-B1O7B1S
		查询结果:
		        主机名:DESKTOP-B1O7B1S
		        地址类型:AF_INET
		        地址长度:4
		        IP地址#1169.255.255.255
		        IP地址#2192.255.255.255
		        IP地址#3192.255.255.255
	------------------------------------------------
		主机名 域名:www.baidu.com
		查询结果:
		        主机名:www.a.shifen.com
		        别名#1:www.baidu.com
		        地址类型:AF_INET
		        地址长度:4
		        IP地址#014.215.177.38

程序步骤:

  1. 对Windows Sockets的动态链接库WS2_32.dll进行初始化。
  2. 获取域名或主机名 本机的话用gethostname进行解析。
  3. 用gethostbyname获取所需要的信息 返回struct hostent类型。
struct hostent
{
	char *h_name;   //地址的正式主机名
	char **h_aliases;  //主机别名,是一个以NULL结束的别名数组
	short h_addrtype;  //地址类型,通常是AF_INET
	short h_length;    //地址的字节长度
	char **h_addr_list;//一个以网络字节顺序表示的以NULL结束的主机地址列表
	#define h_addr h_addr_list[0] //定义列表项的第一项为默认主机地址h_addr
}

struct in_addr: 表示一个32位的IPv4地址:

struct in_addr
{
    unsigned long s_addr;
};

代码:

#include <stdio.h>
#include <winsock2.h>
int main(int argc, char *argv[])
{
	char *host_name;   //要查询的主机名
	char local_host[256];
	if(argc != 2)
	{
		printf("输入错误!\n");
		printf("用法:getip 主机名\n");
		printf("提示:getip localhost");
		return 1;
	}
	//1、对Windows Sockets的动态链接库WS2_32.dll进行初始化
	//WORD sockVersion = MAKEWORD(2, 2);  ====>设定socket版本为2.2
	WSADATA wsaData;
	int retvalue = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if(retvalue != 0)
	{
		printf("WSAStartup 失败:%d\n", retvalue);
		return 1;
	}
	//2、查询获取的是不是本地ip,如果是则获取本机的主机名
	if(strcmp(argv[1], "localhost") == 0)
	{
		// gethostname返回本地主机的标准主机名
		retvalue = gethostname(local_host, sizeof(local_host));
		if(retvalue != 0)
		{
			printf("获取本地主机名失败:%d\n", retvalue);
			return 1;
		}
		host_name = local_host;
	}
	else
		host_name = argv[1];
	printf("主机名 域名:%s\n", host_name);
	//3、gethostbyname用域名或主机名获取IP地址  返回struct hostent类型
	struct hostent *remotehost = gethostbyname(host_name);
	//对返回的结果进行判断
	if(remotehost == NULL)
	{
		//获取错误类型
		DWORD errcode = WSAGetLastError();
		if(errcode == WSAHOST_NOT_FOUND)
		{
			printf("主机没有找到!");
			return 1;
		}
		else if(errcode == WSANO_DATA)
		{
			printf("没找到相应的数据!");
			return 1;
		}
		else
		{
			printf("调用函数失败:%ld\n", errcode);
			return 1;
		}
	}
	else
	{
		//获取地址类型和地址长度
		int i = 0;
		printf("查询结果:\n");
		printf("\t主机名:%s\n", remotehost->h_name);
		//palias二级指针指向了存储别名地址的空间   *palias储别名地址
		for(char **palias = remotehost->h_aliases; *palias != 0; palias++)
		{
			printf("\t别名#%d:%s\n", ++i, *palias);
		}
		printf("\t地址类型:");
		switch(remotehost->h_addrtype)
		{
			case AF_INET:
				printf("AF_INET\n");
				break;
			case AF_NETBIOS:
				printf("AF_NETBIOS\n");
				break;
			default:
				printf("%d\n", remotehost->h_addrtype);
				break;
		}
		printf("\t地址长度:%d\n", remotehost->h_length);
		//如果返回的是IPv4地址,则输出查询到的结果 inet_ntoa:将网络二进制数字转为网络地址
		//inet_aton:将网络地址转为网络二进制数字
		//char *inet_ntoa (struct in_addr);
		int j = 0;
		struct in_addr addr;
		if(remotehost->h_addrtype == AF_INET)
		{
			while(remotehost->h_addr_list[j] != NULL)
			{
				addr.s_addr =  *(u_long *)remotehost->h_addr_list[j++];
				
//				addr.s_addr =  *(u_long *)(*remotehost->h_addr_list++);
//				j++;

				printf("\tIP地址#%d:%s\n", j, inet_ntoa(addr));
				
//				printf("\tIP地址#%d:%s\n", inet_ntoa(*(struct in_addr*)remotehost->h_addr_list[j++]));

//				printf("\tIP地址#%d:%s\n", inet_ntoa(*(struct in_addr*)(*remotehost->h_addr_list++)));
//				j++;
			}
		}
		else if(remotehost->h_addrtype == AF_NETBIOS)
		{
			printf("返回的是ENTBIOS地址");
		}
		//释放WinSock动态链接库相关的资源
		WSACleanup();
    }
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脆订壳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值