程序人生 | UNIX 网络编程之 getaddrinfo 函数详解及使用举例

Linux环境下OpenSSH升级到 OpenSSH_9.8p1(内置保姆级教程并包含openssl升级过程) 2024年7月1日接到安全部门同事邮件通知,目前生产环境及测试环境服务器Openssh存在远程代码执行漏洞(CVE-2024-6387),漏洞等级高,且攻击者可以成功利用该漏洞获得远程root shell最高权限从而执行任意代码及命令,主要受影响版本为8.5p1 阅读详情

本文首发于 2015-01-03 21:04:36

概述

IPv4 中使用 gethostbyname() 函数完成主机名到地址解析,这个函数仅仅支持 IPv4 ,且不允许调用者指定所需地址类型的任何信息,返回的结构只包含了用于存储 IPv4 地址的空间。

IPv6中引入了getaddrinfo()的新API,它是协议无关的,既可用于 IPv4 也可用于IPv6 。

getaddrinfo函数能够处理名字到地址以及服务到端口这两种转换,返回的是一个addrinfo的结构(列表)指针而不是一个地址清单。这些addrinfo结构随后可由socket函数直接使用。

getaddrinfo函数把协议相关性安全隐藏在这个库函数内部。应用程序只要处理由getaddrinfo函数填写的套接口地址结构。该函数在 POSIX规范中定义了。

函数说明

包含头文件:

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

函数原型:

int getaddrinfo( const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result );

参数说明:

  • hostname: 一个主机名或者地址串(IPv4 的点分十进制串或者 IPv6 的 16 进制串)。
  • service:服务名可以是十进制的端口号,也可以是已定义的服务名称,如 ftp、http 等。
  • hints:可以是一个空指针,也可以是一个指向某个 addrinfo 结构体的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。
  • result:本函数通过 result 指针参数返回一个指向 addrinfo 结构体链表的指针。

返回值:

0:成功;非0:出错。

参数设置

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

在6项参数中,对函数影响最大的是nodename,sername和hints.ai_flag,而ai_family只是有地址为v4地址或v6地址的区别。ai_protocol一般为0不作改动。

getaddrinfo在实际使用中的几种常用参数设置:

一般情况下,client/server编程中,server端调用bind(如果面向连接的还需要listen);client则无需调用bind函数,解析地址后直接connect(面向连接)或直接发送数据(无连接)。因此,比较常见的情况有:

  1. 通常服务器端在调用getaddrinfo之前,ai_flags设置AI_PASSIVE,用于bind;主机名nodename通常会设置为NULL,返回通配地址[::]。
  2. 客户端调用getaddrinfo时,ai_flags一般不设置AI_PASSIVE,但是主机名nodename和服务名servname(更愿意称之为端口)则应该不为空。
  3. 当然,即使不设置AI_PASSIVE,取出的地址也并非不可以被bind,很多程序中ai_flags直接设置为0,即3个标志位都不设置,这种情况下只要hostname和servname设置的没有问题就可以正确bind。

上述情况只是简单的client/server中的使用,但实际在使用getaddrinfo和查阅国外开源代码的时候,曾遇到一些将servname(即端口)设为NULL的情况(当然,此时nodename必不为NULL,否则调用getaddrinfo会报错)。

使用须知

1)如果本函数返回成功,那么由result参数指向的变量已被填入一个指针,它指向的是由其中的ai_next成员串联起来的addrinfo结构链表。

struct addrinfo 
{        
	int ai_flags; 
	int ai_family; 
	int ai_socktype; 
	int ai_protocol; 
	size_t ai_addrlen; 
	struct sockaddr *ai_addr; /* 我认为这个成员是这个函数最大的便利。 */
	char *ai_canonname; 
	struct addrinfo *ai_next; 
};

其中,sockaddr结构体为:

在linux环境下,结构体struct sockaddr在/usr/include/linux/socket.h中定义,具体如下:
typedef unsigned short sa_family_t;
struct sockaddr {
        sa_family_t     sa_family;    /* address family, AF_xxx       */
        char            sa_data[14];    /* 14 bytes of protocol address */
}

而且,sockaddr一般要转换为sockaddr_in:

struct sockaddr_in
{ 
  short int sin_family;
  unsigned short int sin_port; 
    struct in_addr sin_addr;          
    unsigned char sin_zero[8];
}   

2)可以导致返回多个addrinfo结构的情形有以下2个:

  1. 如果与hostname参数关联的地址有多个,那么适用于所请求地址簇的每个地址都返回一个对应的结构。
  2. 如果service参数指定的服务支持多个套接口类型,那么每个套接口类型都可能返回一个对应的结构,具体取决于hints结构的ai_socktype成员。

举例来说:如果指定的服务既支持TCP也支持UDP,那么调用者可以把hints结构中的ai_socktype成员设置成SOCK_DGRAM,使得返回的仅仅是适用于数据报套接口的信息。

3)我们必须先分配一个hints结构,把它清零后填写需要的字段,再调用getaddrinfo,然后遍历一个链表逐个尝试每个返回地址。

4)getaddrinfo解决了把主机名和服务名转换成套接口地址结构的问题。

5)如果getaddrinfo出错,那么返回一个非0的错误值。输出出错信息,不要用perror,而应该用gai_strerror,该函数原型为:

const char *gai_strerror( int error );

该函数以getaddrinfo返回的非0错误值的名字和含义为他的唯一参数,返回一个指向对应的出错信息串的指针。

6)由getaddrinfo返回的所有存储空间都是动态获取的,这些存储空间必须通过调用freeaddrinfo返回给系统,该函数原型为:

void freeaddrinfo( struct addrinfo *ai );

ai参数应指向由getaddrinfo返回的第一个addrinfo结构。

这个链表中的所有结构以及它们指向的任何动态存储空间都被释放掉。

示例

1. 根据主机名获取IP地址

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
 
int main(int argc, char **argv)
{
    if (argc != 2) {
        printf("Usag: ./a.out hostname|ip\n");
        exit(1);
    }
    struct addrinfo hints;
    struct addrinfo *res, *cur;
    int ret;
    struct sockaddr_in *addr;
    char ipbuf[16];
	int port;
 
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_INET; /* Allow IPv4 */
    hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
    hints.ai_protocol = 0; /* Any protocol */
    hints.ai_socktype = SOCK_DGRAM;
	ret = getaddrinfo(argv[1], NULL,&hints,&res);
    if (ret < 0) {
		fprintf(stderr, "%s\n", gai_strerror(ret));
        exit(1);
    }
    
    for (cur = res; cur != NULL; cur = cur->ai_next) {
        addr = (struct sockaddr_in *)cur->ai_addr;
        printf("ip: %s\n", inet_ntop(AF_INET, &addr->sin_addr, ipbuf, 16));
		printf("port: %d\n", inet_ntop(AF_INET, &addr->sin_port, (void *)&port, 2));
		//printf("port: %d\n", ntohs(addr->sin_port));
		
    }
    freeaddrinfo(res);
    exit(0);
}

2. 根据主机名和端口号获取地址信息

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <netdb.h>
#include <sys/socket.h>
void main()
{ 
	struct addrinfo *ailist, *aip; 
	struct addrinfo hint; 
	struct sockaddr_in *sinp; 
	char *hostname = "localhost";
	char buf[INET_ADDRSTRLEN]; 
	char *server = "6543"; /* 这是服务端口号 */
	const char *addr; 
	int ilRc;
	hint.ai_family = AF_UNSPEC; /* hint 的限定设置 */
	hint.ai_socktype = 0; /* 这里可是设置 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;
	ilRc = getaddrinfo(hostname, server, &hint, &ailist); 
	if (ilRc < 0) 
	{ 
		printf("str_error = %s\n", gai_strerror(errno)); 
		return; 
	}
 
	/* 显示获取的信息 */
	for (aip = ailist; aip != NULL; aip = aip->ai_next)
	{ 
		sinp = (struct sockaddr_in *)aip->ai_addr;
		addr = inet_ntop(AF_INET, &sinp->sin_addr, buf, INET_ADDRSTRLEN); 
		printf(" addr = %s, port = %d\n", addr?addr:"unknow ", ntohs(sinp->sin_port)); 
	}
}

3. 由内核分配随机端口(再也不担心端口被占了)

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
 
#define MAX_CONN_COUNT 10
 #define INVALID_SOCKET (~0) 
 
int main(int argc, char **argv)
{
	int motionListenPort = 0;
	int motion_sock = 0;
	int	err;
	int	maxconn;
	char familyDesc[32];
	struct sockaddr_storage motion_sock_addr;
	socklen_t alen;
	struct addrinfo *addrs = NULL, *addr, hints;
	int ret;
	int tries = 0;
	
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_INET; /* Allow IPv4 */
    hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
    hints.ai_protocol = 0; /* Any protocol */
    hints.ai_socktype = SOCK_STREAM;
	ret = getaddrinfo(NULL, "0", &hints, &addrs);
    if (ret < 0)
	{
		fprintf(stderr, "%s\n", gai_strerror(ret));
        exit(1);
    }
	
    for (addr = addrs; addr != NULL; addr = addr->ai_next) {
		/* Create the socket. */
		if ((motion_sock = socket(addr->ai_family, SOCK_STREAM, 0)) == INVALID_SOCKET)
		{
			fprintf(stderr, "Error:could not create socket for the motion\n");
			continue;
		}
 
		/* Bind it to a kernel assigned port on localhost and get the assigned port via getsockname(). */
		if (bind(motion_sock, addr->ai_addr, addr->ai_addrlen) < 0)
		{
			fprintf(stderr, "Error: could not bind socket for the motion\n");
			close(motion_sock);
			motion_sock = INVALID_SOCKET;
			continue;
		}
 
		alen = sizeof(motion_sock_addr);
		if (getsockname(motion_sock, (struct sockaddr *) &(motion_sock_addr), &alen) < 0)
		{
			fprintf(stderr, "could not get address of socket for the motion\n");
			close(motion_sock);
			motion_sock = INVALID_SOCKET;
			continue;
		}
 
		/* Resolve the motion listen port. */
		switch(motion_sock_addr.ss_family)
		{
			case AF_INET:
				{
					struct sockaddr_in *motion_addr = (struct sockaddr_in *) &motion_sock_addr;
					motionListenPort = ntohs(motion_addr->sin_port);
					strcpy(familyDesc, "IPv4");
					fprintf(stdout, "motionListenPort=%d, familyDesc = %s\n", motionListenPort, familyDesc);
					break;
				}
			case AF_INET6:
				{
					struct sockaddr_in6 *motion_addr = (struct sockaddr_in6 *) &motion_sock_addr;
					motionListenPort = ntohs(motion_addr->sin6_port);
					strcpy(familyDesc, "IPv6");
					fprintf(stdout, "motionListenPort=%d, familyDesc = %s\n", motionListenPort, familyDesc);
					break;
				}
			default:
				{
					fprintf(stderr, "Error:unrecognized address family \"%d\" for the motion\n", motion_sock_addr.ss_family);
					continue;
				}
		}
 
		/* 监听 */
		maxconn = MAX_CONN_COUNT;
		err = listen(motion_sock, maxconn);
		if (err < 0)
		{
			fprintf(stderr, "could not listen on socket for the motion\n");
			close(motion_sock);
			motion_sock = INVALID_SOCKET;
			continue;
		}
    }
	
	if (motion_sock == INVALID_SOCKET)
		goto listen_failed;
 
	/* XXXXXX	socket通信过程 */
	
	
	freeaddrinfo(addrs);
	close(motion_sock);
	return 0;
	
listen_failed:
	fprintf(stderr, "Error: failed to listen for the motion\n");
	if (addrs)
		freeaddrinfo(addrs);
 
	if (motion_sock != INVALID_SOCKET)
		close(motion_sock);
	motion_sock = INVALID_SOCKET;
	return -1;
}

4. 使用ioctl获取指定网卡IP地址

#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
 
#define ETH_NAME	"eth0"
 
int main()
 
{
	int sock;
	struct sockaddr_in sin;
	struct ifreq ifr;
	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == -1)
	{
		perror("socket");
		return -1;		
	}
 
	strncpy(ifr.ifr_name, ETH_NAME, IFNAMSIZ);
	ifr.ifr_name[IFNAMSIZ - 1] = 0;
	if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
	{
		perror("ioctl");
		return -1;
	}
 
	memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
	fprintf(stdout, "eth0: %s\n", inet_ntoa(sin.sin_addr));
 
	return 0;
}

5. 使用ping指令,根据hostname获取ip地址

本例未用 getaddrinfo,而是采用shell指令方法(不推荐)。

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>


//使用ping指令,根据hostname获取ip地址
int getIpAddrByHostname(char *hostname, char* ip_addr, size_t ip_size)
{
	char command[256];
	FILE *f;
	char *ip_pos;
 
	snprintf(command, 256, "ping -c1 %s | head -n 1 | sed 's/^[^(]*(\\([^)]*\\).*$/\\1/'", hostname);
	fprintf(stdout, "%s\n", command);
	if ((f = popen(command, "r")) == NULL)
	{
		fprintf(stderr, "could not open the command, \"%s\", %s\n", command, strerror(errno));
		return -1;
	}
 
	fgets(ip_addr, ip_size, f);
	fclose(f);
 
	ip_pos = ip_addr;
	for (;*ip_pos && *ip_pos!= '\n'; ip_pos++);
	*ip_pos = 0;
 
	return 0;
}

int main()
{
	char addr[64] = {0};
	getIpAddrByHostname("localhost", addr, INET_ADDRSTRLEN);
	fprintf(stdout, "localhost: %s\n", addr);
	return 0;
}

欢迎关注我的微信公众号【数据库内核】:分享主流开源数据库和存储引擎相关技术。

标题网址
GitHubhttps://dbkernel.github.io
知乎https://www.zhihu.com/people/…
思否(SegmentFault)https://segmentfault.com/u/db…
掘金https://juejin.im/user/5e9d3e…
开源中国(oschina)https://my.oschina.net/dbkernel
博客园(cnblogs)https://www.cnblogs.com/dbkernel
高精地图语义分割标注 什么是语义分割?语义分割与目标检测的区别?语义分割的关键应用场景有哪些?高精地图语义分割标注的难点? 阅读详情

相关推荐

手把手教你搞定Pattern Recognition Letters的LaTeX投稿(附elsarticle.cls生成避坑指南)

本文详细指导如何在Pattern Recognition Letters(PRL)期刊上使用LaTeX进行投稿,特别针对elsarticle.cls文件的生成与常见问题提供避坑指南。从模板准备、文件上传到投稿后的验证,系统梳理全流程技术要点,帮助研究者高效完成学术论文投稿。

weixin_33824385的博客 430

getaddrinfo()函数详解

getaddrinfo()函数详解1. 概述IPv4中使用gethostbyname()函数完成主机名到地址解析,这个函数仅仅支持IPv4,且不允许调用者指定所需地址类型的任何信息,返回的结构只包含了用于存储IPv4地址的空间。IPv6中引入了getaddrinfo()的新API,它是协议无关的,既可用于IPv4也可用于IPv6。getaddrinfo函数能够处理名字到地址以及服务到端口这两种转...

weixin_30591551的博客 2720

python进行windows系统UI自动化之【pyautoit】

一般以我们平时操作,会从下图上方的地址栏进行操作,这里注意可以直接从下方的文件名处,输入对应的绝对地址,如:F:\程序设计书籍\《啊哈!pyautoit 是一个用python写的基于AutoItX3.dll的接口库,用来进行windows窗口的一系列操作,也支持鼠标键盘的操作。点击上访的图标,进行拖拉,到想访问的位置,注意下图两个红框中的数值,上面的框表示页面的标题和类,下面的框表示控件的类和序号(一般连起来使用)打开Auto Window Info(x64)或Auto Window Info(x86)

weixin_43936332的博客 9318

浅谈getaddrinfo函数的超时处理机制

转自:http://zx-star2002.blog.163.com/blog/static/3044645020153993321890/ 一 getaddrinfo简介          getaddrinfo提供独立于协议的名称解析,它的作用是将网址和服务,转换为IP地址和端口号的。比如说,当我们输入一个http://www.baidu.com之类的网址,getaddri

haima1998的专栏 1万+

映泰TB250-BTC主板魔改BIOS支持8/9代CPU实战与开机故障排查

BIOS(基本输入输出系统)是计算机硬件与操作系统之间的桥梁,负责初始化硬件和提供运行时服务。其工作原理是通过存储在主板芯片中的固件程序,在上电自检(POST)阶段完成对CPU、内存等关键组件的检测与配置。魔改BIOS的技术价值在于突破硬件限制,通过修改微码和电源管理模块,让旧平台支持新处理器,从而以极低成本实现性能跃升,在预算有限或追求极致性价比的DIY、办公和软路由等应用场景中极具吸引力。本文以映泰TB250-BTC矿板为例,详细解析了通过软刷方式刷入魔改BIOS,并重点解决了刷写后常见的“开机风扇转一

weixin_29164185的博客 410

基于 STM32 的手持式安检金属探测器设计与实现

【代码】基于 STM32 的手持式安检金属探测器设计与实现。

weixin_42300449的博客 901

getaddrinfo()

getaddrinfo接口 getaddrinfo通过res来返回一个指向struct addrinfo结构链表的指针(注意这里返回的是一个链表),struct addrinfo结构的定义如下所示:   struct addrinfo { int ai_flags; /* Input flags. */ int ai_family; /* Protocol...

TuxedoLinux的博客 796

SAP 系统中的数字签名解决方案及应用案例分析

在当前企业信息化及数字化转型的大背景下,数据安全与身份认证显得尤为重要。数字签名技术作为保障数据真实性和完整性的重要手段,在 SAP 系统中得到了广泛应用。本文将详细探讨 SAP 系统中部分应用场景如何利用数字签名技术满足业务需求,涵盖 SAP Single Sign-On、质量管理、过程工业生产计划以及 SAP ArchiveLink 内容服务器等方面,力求通过深入解读,帮助读者更好地理解和应用这一关键技术。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 529

关于getaddrinfo()函数阻塞时间过长的问题

使用select()函数对getaddrinfo()函数进行封装

欲穷千里目,更上一层楼 3432

26. Fabric2.2 司法存证的智能合约分析

有很多同学反馈 Fabric 智能合约读起来比较费劲,对于新手不友好看不懂,这里选择一个司法存证的智能合约,阅读、分析智能合约基础框架与核心流程代码,培养大家智能合约编写的方法论。

菜鸟的博客 1340

vue2/3 - 详细实现内网使用离线高德地图功能,在vue中无需网络离线使用高德地图相关功能,高德地图如何离线加载详细教程(内网部署及使用),提供最新完整的瓦片资源下载及相关工具(示例代码,一键复制

vue,vue2,vue3,高德地图,离线使用高德地图,高德地图瓦片官方下载,vue内网使用高德地图离线无网络,断网情况下使用高德地图,vue离线高德地图教程,如何实现内网部署高德地图,无需联网离线使用,vue+ts实现离线高德地图 内网离线高德地图,如何在高德地图Vue项目中下载离线地图,高德离线地图加载不出来,高德地图离线使用不显示怎么办,怎么解决vue内网使用离线高德地图加载失败问题,vue实现离线地图+高德瓦片,vue引入高德离线地图,vue项目如何使用离线高德地图和自定义地图样式,高德离线地图的下

✅ 精选推荐文章 1万+

CV之FR:基于face和cv2库调用摄像头(或视频)实现人脸识别并标注姓名标签包装为GUI界面产品(先指定要识别已知人脸的文件夹转为numpy_array+输入新图片遍历已有numpy_array)

CV之FR:基于face和cv2库调用摄像头(或视频)实现人脸识别并标注姓名标签包装为GUI界面产品(先指定要识别已知人脸的文件夹转为numpy_array+输入新图片遍历已有numpy_array)

头部AI社区如有邀博主AI主题演讲请私信—心比天高,仗剑走天涯,保持热爱,奔赴向梦想!低调,专注,谦虚,自律,反思,成长,还算比较正能量的博主,公益免费传播…内心特别想在AI界做出一些可以推进历史进程影响力的技术(兴趣使然,有点小情怀,也有点使命感呀 1万+

uniapp开发小程序保存图片权限获取失败一直走fail?本地能保存,线上版就不行! 原来是这个问题!

通过这次经历,我发现线上版小程序和开发版、体验版的权限控制差异较大。如果你也遇到类似的问题,首先要检查是否已勾选“采集用户隐私”,并确保在提交审核时配置了隐私条款。这个设置非常关键,避免像我一样浪费了不少时间和版本。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1078

unix网络编程之getaddrinfo函数详解及使用举例

getaddrinfo函数使用示例如下: (1)根据主机名获取IP地址: #include #include #include #include #include #include #include int main(int argc, char **argv) { if (argc != 2) { printf("Usag: ./a.out hostn

竹林听雨 6835

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Unix/Linux编程:getaddrinfo、getnameinfo

getaddrinfo getaddrinfo是gethostbyname、gethostbyaddr的升级版 getaddrinfo()函数将主机和服务名转换成 IP 地址和端口号,它作为过时的 gethostbyname()和 getservbyname()函数的(可重入的)接替者被定义在了 POSIX.1g 中。它是协议无关的,既可用于IPv4也可用于IPv6。 给定一个主机名和服务器名,getaddrinfo()函数返回一个 socket 地址结构列表,每个结构都包含一个地址和端口号

OceanStar的博客 3017

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

《UNIX 网络编程-卷1》阅读笔记12: 名字与地址转换

第十一章是《UNIX网络编程》中极其关键的一章。到此为止,书中所有例子都使用数值地址表示主机(如 206.6.226.33),使用数值端口号标识服务器(如端口 13 代表 daytime 服务器)。但出于三个理由,我们应该使用名字而非数值:名字更容易记住;数值地址可以变动而名字保持不变;随着向 IPv6 过渡,数值地址变得非常长,手工键入数值地址更容易出错。本章的核心主题是实现主机名与 IP 地址以及服务名与端口号之间的转换。早期的函数(如)仅支持 IPv4,且存在线程不安全和不可重入的问题。

2305

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

getaddrinfo函数

getaddrinfo 函数允许将将一个主机名和一个服务名映射到一个地址。函数原型:#include <sys/socket.h> #include <netdb.h>int getaddrinfo(const char *restrict host, const char *restrict service, const struct addrinfo *restrict hint, struct

hjhomw的博客 609

深入理解 Linux 系统下的关键网络接口和函数,gethostent,getaddrinfo,getnameinfo

Unix 系统下的关键网络接口和函数,gethostent,getaddrinfo,getnameinfo

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 477

网络编程之API函数

网络编程中的API(应用程序编程接口)函数是开发人员用于实现网络通信的关键工具。这些API函数提供了各种功能,包括套接字创建、连接管理、数据传输、错误处理等。以下是一些常见的网络编程API函数,主要基于C语言中的BSD套接字API和Windows套接字API(Winsock)。

浩瀚之水的专栏 1335

gethostbyname & getaddrinfo

struct sockaddr { sa_family_t sin_family;//地址族    char sa_data[14]; //14字节,包含套接字中的目标地址和端口信息 }; struct sockaddr_in { sa_family_t sin_family; uint16_t sin_port; //2字节 struct in_addr sin_addr; //4字节 char

gdut17的博客 537

Beej的网络编程入门教程 第六篇 必要的系统调用 getaddrinfo

5.必要的系统调用       这一节我们开始接触那些允许你访问网络功能的系统调用。当你在UNIX或其它支持套接字API的系统上(BSD,Windows,Linux,Mac等等)调用这些功能时系统会自动为你做好所有的工作。       因为不知道按什么顺序调用,许多人到这里非常困惑。你可能已经发现了我没有使用完整的例子。好的,为了解决这个问题我试着按在程序中调用的顺序来按排章节。   

luck_wei的专栏 1317

libuv 异步 DNS 工具函数详解:uv_getaddrinfo 与 uv_getnameinfo 的用法与实现原理

libuv 将 POSIX 标准库中的 `getaddrinfo(3)`(主机名/服务名解析为地址)与 `getnameinfo(3)`(地址反向解析为主机名/服务名)封装为异步请求 API,让 DNS 查询不再阻塞事件循环。本文基于 [DNS 工具函数官方文档](https://link.gitcode.com/i/d4db766e3193e0472169aacf2094916b),结合 [in

gitblog_00322的博客 741

python socket函数_Python socket 函数 getaddrinfo | 学步园

# -*- coding: cp936 -*-socket.getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0)#根据给定的参数host/port,相应的转换成一个包含用于创建socket对象的五元组,#参数host为域名,以字符串形式给出代表一个IPV4/IPV6地址或者None.#参数port如果字符串形式就代表一个服...

weixin_31455121的博客 594

Unix网络编程环境搭建

原文地址http://blog.youkuaiyun.com/a649518776/article/details/6724121 下面开始用简单但典型的客户端和服务器端程序说明如何进行网络编程。这一小节讲的是客户端,一个用来连接并读取服务器发送来的时间的客户端。 这里涉及到了编写代码,因此要 搭建unix网络编程环境 unix系统我没安装,系统不易获得而且也没必要安装unix。用

Cas_pian的专栏 782

UNIX网络编程——名字与地址转换(gethostbyname,gethostbyaddr,getservbyname,getservbyport,getaddrinfo,getnameinfo函数)

名字和数值地址间进行转换的函数:gethostbyname和gethostbyaddr在主机名字与IPv4地址之间进行转换。getservbyname和getservbyport在服务器名字和端口号之间进行转换。还有两个协议无关的转换函数:getaddrinfo和getnameinfo,分别用于主机名字和IP地址之间以及服务名字和端口之间的转换。1.gethostbyname函数     通过传入

ctthuangcheng 3397

unix网络编程环境

搭建unix网络编程环境 unix系统我没安装,系统不易获得而且也没必要安装unix。用linux是最佳选择。再者我本来就是ubuntu系统,所以就在ubuntu下搭建环境了。 1,安装编译器,为了齐全还是安装一下build-essential [python] view plaincopy sudo apt-ge

u012994993的专栏 720
上一篇: 程序人生 | Linux Daemon 程序设计示例
下一篇: 推荐 | 一体化实时 HTAP 数据库 StoneDB,如何替换 MySQL 并实现近百倍性能提升
dbkernel
博客等级 码龄4年 60粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值