获得本机的主机名及所有IPv4、IPv6地址


1.查询本机的主机名称及IP地址,并从键盘输入某网站的域名解析其IP地址。

gethostname()

该函数用来查询本地计算机主机名字。

函数原型
int gethostname(char *name, int namelen)
函数参数
Name:指向用于存放主机名字的缓冲区,就是一字符数组。
Namelen:是缓冲区的大小,也就是字符数组name的大小。
返回值
函数调用成功则返回0。函数调用失败,则返回SOCKET_ERROR,进一步的出错信息可调用WSAGetLastError()获取。

hostent结构包含对应给定主机名的IP地址等信息,其定义如下:

struct hostent 
{
  char  *h_name;    //主机的规范名
  char  **h_aliases;   //主机的别名
  int   h_addrtype;    //主机ip地址的类型(AF_INET)
  int   h_length;      //主机ip地址的长度(4)
  char  **h_addr_list;  //主机ip地址列表(网络字节序)
};

其中,字符指针h_name指向主机的正规名字;
指向字符数组的指针h_aliases指向的是 一个以空指针结尾的可选主机名队列;
h_addrtype保存主机地址的类型,对于Windows Sockets来说,其值总是AF_INET;
h_legnth 是每个地址的长度(字节数),对应于类型AF_INET来说,这个域的值为4;
指针h_addr_list 指向的是一个以空指针结尾的主机地址的列表,列表中的地址是以网络字节顺序排列的。

int main()
{
	struct hostent* hptr;
	char** pptr;
	char hostname[256];
	//初始化WinSock DLL 
	WORD wVersionRequested;
	WSADATA wsaData;
	wVersionRequested = MAKEWORD(2, 2);  //生成版本号2.2
	if (WSAStartup(wVersionRequested, &wsaData) != 0)return 0;
	if (gethostname(hostname, sizeof(hostname))) 
	{
		cout << "gethostname calling error" << endl;
		WSACleanup();return 0;
	}
	cout << "主机名为:" << hostname << endl;
	if ((hptr = gethostbyname(hostname)) == NULL) 
	{
		cout << "名字解析失败" << endl;
		WSACleanup();
		return 0;
	}
	/***输出IP地址***/
	pptr = hptr->h_addr_list;
	cout << "本机IP地址:" << endl;
	while (*pptr != NULL) 
	{
		cout << inet_ntoa(*(struct in_addr*)(*pptr)) << endl;
		pptr++;
	}
	cout << "输入要解析的域名:" << endl;
	cin >> hostname;
	if ((hptr = gethostbyname(hostname)) == NULL) 
	{
		cout << "名字解析失败" << endl;
		WSACleanup();
		return 0;
	}
	/***输出IP地址***/
	pptr = hptr->h_addr_list;
	cout << "主机IP地址:" << endl;
	while (*pptr != NULL) 
	{
		cout << inet_ntoa(*(struct in_addr*)(*pptr)) << endl;
		pptr++;
	}
	WSACleanup();
	return 0;
}

2.查询本机的所有IPv6地址

getaddrinfo( )

函数原型:int getaddrinfo(const char *hostname,const char *service,const struct addrinfo *hints,struct addrinfo **result)
函数参数:
const char *hostname, //一个主机名或者地址串(IPv4的点分十进制串或者IPv6的16进制串)
const char *service, //服务名可以是十进制的端口号,NULL
const struct addrinfo *hints,//可以是一个空指针,也可以是一个指向某个addrinfo结构体的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。
struct addrinfo **result //返回一个指向addrinfo结构体链表的指针
);

int get_ipv6()
{
	struct addrinfo hint;
	struct sockaddr_in6* sinp6;
	struct addrinfo* ailist, * aip;
	const char* port = "1";      //端口号 
	int ilRc;
	char hostname[255] = { 0 }; //主机名 
	hint.ai_family = AF_INET6;        //hint 的限定设置
	hint.ai_socktype = SOCK_STREAM;   //这里可是设置 socket type    比如  SOCK_DGRAM
	hint.ai_flags = AI_PASSIVE;       // flags 的标志很多。常用的有AI_CANONNAME;
	hint.ai_protocol = 0;             //设置协议  一般为0,默认
	hint.ai_addrlen = 0;              //下面不可以设置,为0,或者为NULL
	hint.ai_canonname = NULL;
	hint.ai_addr = NULL;
	hint.ai_next = NULL;
	gethostname(hostname, sizeof(hostname));
	ilRc = getaddrinfo(hostname, port, &hint, &ailist); //通过主机名获得地址信息
	if (ilRc < 0)
	{
		char str_error[100];
		strcpy(str_error, (char*)gai_strerror(errno));
		printf("str_error = %s", str_error);
		return 0;
	}
	if (ailist == NULL)
	{
		printf("sorry not find the IP address,please try again \n");
	}
	for (aip = ailist; aip != NULL; aip = aip->ai_next) //显示获取的信息
	{
		aip->ai_family = AF_INET6;
		sinp6 = (struct sockaddr_in6*)aip->ai_addr;    
		int i;
		printf("ipv6 addr = ");
		for (i = 0; i < 16; i++)
		{
			if (((i - 1) % 2) && (i > 0))
			{
				printf(":");
			}
			printf("%02x", sinp6->sin6_addr.u.Byte[i]);
		}
		printf(" \n");
		printf(" \n");
	}
	return -1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

新西兰做的饭

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

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

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

打赏作者

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

抵扣说明:

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

余额充值