IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> linux网络编程(getaddrinfo和gethostbyname函数详解) -> 正文阅读

[网络协议]linux网络编程(getaddrinfo和gethostbyname函数详解)

一、getaddrinfo

函数原型: int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
函数功能:根据hints指定的参数要求,获取服务器node的信息,并将获取的结果存储到res中
函数参数:node 服务器的域名或者IP地址
          service 服务的十进制端口字符串或者协议类型,如“8099”、“http”
          hints 输入参数,指定获取服务器信息的参数
          res 存储返回的服务器信息
返回值:成功返回0,失败返回对应的错误信息

struct addrinfo结构体如下:

struct addrinfo {
   int              ai_flags;
   int              ai_family;
   int              ai_socktype;
   int              ai_protocol;
   socklen_t        ai_addrlen;
   struct sockaddr *ai_addr;
   char            *ai_canonname;
   struct addrinfo *ai_next;
};

在getaddrinfo函数之前通常需要对以下6个参数进行以下设置:nodename、servname、hints的ai_flags、ai_family、ai_socktype、ai_protocol。

ai_flags用来指定如何处理地址和名字,它的取值有3个:

  • AI_PASSIVE 当此标志置位时,表示调用者将在bind()函数调用中使用返回的地址结构。当此标志不置位时,表示将在connect()函数调用中使用。
    当节点名位NULL,且此标志置位,则返回的地址将是通配地址。
    如果节点名NULL,且此标志不置位,则返回的地址将是回环地址。
  • AI_CANNONAME 当此标志置位时,在函数所返回的第一个addrinfo结构中的ai_cannoname成员中,应该包含一个以空字符结尾的字符串,字符串的内容是节点名的正规名。
  • AI_NUMERICHOST 当此标志置位时,此标志表示调用中的节点名必须是一个数字地址字符串。

在WiFi产品的开发中,我们比较常用的场景是根据主机的域名解析主机所使用的ip地址,ai_flags通常设置为0。

ai_family用来指定需要解析的域名对应的IP地址类型,可以是IPv4或者IPv6,如果不知道主机域名对应的IP类型,可以将这个参数设置成AF_UNSPEC,它的参数如下:

  • AF_INET 协议类型为IPv4
  • AF_INET6 协议类型为IPv6
  • AF_UNSPEC 不指定协议类型

ai_protocol用来指定协议类型,ai_family只能指定IPv4或者IPv6,ai_protocal则更加细化,可以指定为TCP、UDP、IP等等,具体的取值如下:

  • IPPROTO_IP IP协议
  • IPPROTO_IPV4 IPv4协议
  • IPPROTO_IPV6 IPv6协议
  • IPPROTO_UDP UDP协议
  • IPPROTO_TCP TCP协议

ai_socktype用来指定协议的数据类型,它的取值如下:

  • SOCK_STREAM 数据流,对应TCP协议
  • SOCK_DGRAM 数据报,对应UDP协议

剩余的几个参数在getaddrinfo函数的hints参数中没有用到,无需设置。

getaddrinfo函数返回的服务器信息存储在res变量中,一个域名可以对应多个IP地址,所以addrinfo结构体是一个链表,可以通过遍历链表得到所有的IP地址信息。

示例:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int PhaseServerAddr(char *host)
{
	int rc = -1;
	char *ip;
	struct addrinfo *result = NULL;
	struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL};

    if ((rc = getaddrinfo(host, NULL, &hints, &result)) == 0)
	{
		struct addrinfo* res = result;

		printf("AF_INET:%d\r\n",AF_INET);
		while (res)
		{

			ip = inet_ntoa(((struct sockaddr_in*)(res->ai_addr))->sin_addr);
			printf("ip type:%d addr:%s\r\n",res->ai_family,ip);
			res = res->ai_next;
		}
		freeaddrinfo(result);
	}
}

int main()
{
	PhaseServerAddr("www.baidu.com");
}

执行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jiqSy5PD-1628238838673)(FEF6981A6A8F4448A3A3595010BF9512)]

把得到的IP地址放到浏览器中,也可以直接打开百度主页。

二、gethostbyname

函数原型:struct hostent *gethostbyname(const char *name);
函数功能:根据域名解析IP地址
函数参数:name 域名,如“www.baidu.com”
返回值:成功返回存储IP地址的结构体,失败返回NULL

struct hostent结构体的原型为:

struct hostent {
   char  *h_name;            /* official name of host */
   char **h_aliases;         /* alias list */
   int    h_addrtype;        /* host address type */
   int    h_length;          /* length of address */
   char **h_addr_list;       /* list of addresses */
}
  • h_name:官方域名。官方域名代表某一主页,但实际上一些著名公司的域名并未用官方域名注册。
  • h_aliases:别名,可以通过多个域名访问同一主机。同一 IP 地址可以绑定多个域名,因此除了当前域名还可以指定其他域名。
  • h_addrtype:指明服务器的地址类型,IPv4 对应 AF_INET,IPv6 对应 AF_INET6。
  • h_length:保存IP地址长度。IPv4 的长度为 4 个字节,IPv6 的长度为 16 个字节。
  • h_addr_list:存储域名对应的IP地址,一个域名可以对应多个IP地址。

示例:

void PhaseServer()
{
	char **ptr;
	struct hostent *hst;
	char str[16];
	hst = gethostbyname("www.baidu.com");
	if(NULL != hst)
	{
		printf("offical name:%s\r\n",hst->h_name==NULL?"NULL":hst->h_name);

		for(ptr = hst->h_aliases;*ptr != NULL;ptr++)
		{
            printf(" alias:%s\r\n",*ptr);
		}

		switch(hst->h_addrtype) 
		{
			case AF_INET:
			case AF_INET6:
			ptr=hst->h_addr_list;

			for(;*ptr!=NULL;ptr++)
			{
				char *p = inet_ntop(hst->h_addrtype, *ptr, str, sizeof(str));
			    if(NULL != p)
					printf(" address:%s\r\n", p);
			}
			break;
			default:
			printf("unknown address type/n");
			break;
		}

	}
}

运行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5HALkcBV-1628238838675)(45E731DF1E214048B5467C2BE12C8C90)]

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 12:25:58  更:2021-08-07 12:26:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 17:38:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码