getaddrinfo()函数详解
Socket的地址查询函数
http://blog.sina.com.cn/s/blog_988c054b010139e3.html
http://www.cnblogs.com/cxz2009/archive/2010/11/19/1881693.html
包含头文件
#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结构体的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。举例来说:如果指定的服务既支持TCP也支持UDP,那么调用者可以把hints结构中的ai_socktype成员设置成SOCK_DGRAM使得返回的仅仅是适用于数据报套接口的信息。
result:本函数通过result指针参数返回一个指向addrinfo结构体链表的指针。
返回值:0——成功,非0——出错
addrinfo结构体原型
int ai_flags; //AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST
int ai_family; //AF_INET,AF_INET6
int ai_socktype; //SOCK_STREAM,SOCK_DGRAM
int ai_protocol; //IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc.
size_t ai_addrlen; //must be zero or a null pointer
char* ai_canonname; //must be zero or a null pointer
struct sockaddr* ai_addr; //must be zero or a null pointer
struct addrinfo* ai_next; //must be zero or a null pointer
}
其中ai_flags、ai_family、ai_socktype说明如下:
参数 取值 值 说明
ai_family AF_INET 2 IPv4
AF_INET6 23 IPv6
AF_UNSPEC 0 协议无关
ai_protocol IPPROTO_IP 0 IP协议
IPPROTO_IPV4 4 IPv4
IPPROTO_IPV6 41 IPv6
IPPROTO_UDP 17 UDP
IPPROTO_TCP 6 TCP
ai_socktype SOCK_STREAM 1 流
SOCK_DGRAM 2 数据报
ai_flags AI_PASSIVE 1 被动的,用于bind,通常用于server socket
AI_CANONNAME 2
AI_NUMERICHOST 4 地址为数字串
对于ai_flags值的说明:
AI_NUMERICHOST | AI_CANONNAME | AI_PASSIVE
如上表所示,ai_flags的值范围为0~7,取决于程序如何设置3个标志位,比如设置ai_flags为 “AI_PASSIVE|AI_CANONNAME”,ai_flags值就为3。三个参数的含义分别为:
(1)AI_PASSIVE
当此标志置位时,表示调用者将在bind()函数调用中使用返回的地址结构。当此标志不置位时,表示将在connect()函数调用中使用。当节点名位
NULL,且此标志置位,则返回的地址将是通配地址。如果节点名NULL,且此标志不置位,则返回的地址将是回环地址。
(2)AI_CANNONAME当此标志置位时,在函数所返回的第一个addrinfo结构中的ai_cannoname成员中,应该包含一个以空字符结尾的字符串,字符串的内容是节点名的正规名。
(3)AI_NUMERICHOST当此标志置位时,此标志表示调用中的节点名必须是一个数字地址字符串。
addrinfo结构中的ai_flags有以下几种值:
- AI_ADDRCONFIG: 查询配置的地址类型(IPv4或IPv6).
- AI_ALL: 查找IPv4和IPv6地址(仅用于AI_V4MAPPED).
- AI_CANONNAME: 需要一个规范名(而不是别名).
- AI_NUMERICHOST: 以数字格式返回主机地址.
- AI_NUMERICSERV: 以端口号返回服务.
- AI_PASSIVE: socket地址用于监听绑定.
- AI_V4MAPPED: 如果没有找到IPv6地址, 则返回映射到IPv6格式的IPv6地址.
如果getaddrinfo失败, 不能使用perror或strerror来生成错误信息, 应该使用gai_strerror将返回的错误码转换成错误信息:
- 原型: const char *gai_strerror(int error);
- 头文件: <netdb.h>
int connect_2_server(char* host, int port, int verb, PLAYER_INTERRUPT_CBK interrupt_cbk)
{
int ret = 0;
int ai_port = 0;
int ai_family = 0;
#ifdef LINUX_OS
char ai_host[INET6_ADDRSTRLEN] = {0};
#endif
char portname[6];
struct addrinfo *houts = NULL;
struct addrinfo *ph = NULL;
struct sockaddr_in* sinp = NULL;
struct addrinfo hints;
hints.ai_flags = 0;
hints.ai_family = 0;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_addrlen = 0;
hints.ai_addr = NULL;
hints.ai_canonname = NULL;
hints.ai_next = NULL;
sprintf(portname,"%d",port);
if(getaddrinfo(host, portname, &hints, &houts)){
printf("tcp: %s error, getaddrinfo return null\n",__FUNCTION__);
return GX_TCP_ERROR_FATAL;
}
ph = houts;
retry_host:
if(ph == NULL){
printf("cannot find hostname\n");
freeaddrinfo(houts);
return GX_TCP_ERROR_FATAL;
}
sinp = (struct sockaddr_in*)ph->ai_addr;
ai_family = ph->ai_family;
ai_port = ntohs(sinp->sin_port);
if(ai_port != port){
printf("ai_port:%d port:%d\n",ai_port,port);
ph = ph->ai_next;
goto retry_host;
}
#ifdef LINUX_OS
if(inet_ntop(ph->ai_family,&sinp->sin_addr, ai_host, INET6_ADDRSTRLEN) == NULL){
ph = ph->ai_next;
printf("get addr %s\n",strerror(errno));
goto retry_host;
}
#endif
//printf("family is %s\n", (ai_family==AF_INET)?"AF_INET":"AF_INET6");
//printf("host is %s\n", ai_host);
//printf("port is %d\n", ai_port);
ret = connect2server_with_af(ai_family,(struct sockaddr*)sinp, verb, interrupt_cbk);
if(ret < 0){
ph = ph->ai_next;
goto retry_host;
}
freeaddrinfo(houts);
return ret;
}
getaddrinfo()函数详解的更多相关文章
- getaddrinfo()函数详解-(转自 cxz2009)
1. 概述IPv4中使用gethostbyname()函数完成主机名到地址解析,这个函数仅仅支持IPv4,且不允许调用者指定所需地址类型的任何信息,返回的结构只包含了用于存储IPv4地址的空间.IPv ...
- malloc 与 free函数详解<转载>
malloc和free函数详解 本文介绍malloc和free函数的内容. 在C中,对内存的管理是相当重要.下面开始介绍这两个函数: 一.malloc()和free()的基本概念以及基本用法: 1 ...
- NSSearchPathForDirectoriesInDomains函数详解
NSSearchPathForDirectoriesInDomains函数详解 #import "NSString+FilePath.h" @implementation ...
- JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解
二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...
- Linux C popen()函数详解
表头文件 #include<stdio.h> 定义函数 FILE * popen( const char * command,const char * type); 函数说明 popen( ...
- kzalloc 函数详解(转载)
用kzalloc申请内存的时候, 效果等同于先是用 kmalloc() 申请空间 , 然后用 memset() 来初始化 ,所有申请的元素都被初始化为 0. view plain /** * kzal ...
- Netsuite Formula > Oracle函数列表速查(PL/SQL单行函数和组函数详解).txt
PL/SQL单行函数和组函数详解 函数是一种有零个或多个参数并且有一个返回值的程序.在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句,函数主要分为两大类: 单行函数 ...
- jQuery.attr() 函数详解
一,jQuery.attr() 函数详解: http://www.365mini.com/page/jquery-attr.htm 二,jQuery函数attr()和prop()的区别: http: ...
- memset函数详解
语言中memset函数详解(2011-11-16 21:11:02)转载▼标签: 杂谈 分类: 工具相关 功 能: 将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大 ...
随机推荐
- BZOJ 1029: [JSOI2007]建筑抢修 优先队列
1029: [JSOI2007]建筑抢修 Time Limit: 4 Sec Memory Limit: 162 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- HDU 4268 Alice and Bob 贪心STL O(nlogn)
B - Alice and Bob Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u D ...
- angularjs鼠标移入移出实现显示隐藏
<tr ng-repeat="item in items track by $index"> <td data-title="操作" alig ...
- MySQL在控制台上以竖行显示表格数据
直接在SQL语句后面加\G即可,如: select * from user limit 10\G; 如果想要知道这些参数可以直接在命令行后面加入\?
- matlab运行过程中出现找不到指定模块问题解决
对于matlab08版本以前的解决方法: 修改改环境变量: 新建变量名:BLAS_VERSION 变量值:D:\matlab7\bin\win32\atlas_Athlon.dll 在你的安装文件夹里 ...
- C#线程安全的那些事
还是上一次,面试的时候提到了C#线程安全的问题,当时回答的记不太清了,大概就是多线程同是调用某一个函数时可能会照成数据发生混乱,运行到最后发现产生的结果或数据并不是自己想要的,或是跨线程调用属性或方法 ...
- [MySql]锁表与解锁
摘要 为啥会出现锁表的情况?锁表会导致数据表的其他操作超时,频繁的插入修改查询很容易出现锁表的情况.如果遇到这种情况,临时的解决办法,可以通过下面的方式进行解锁.如果长期有效的解决,那么就需要优化项目 ...
- Spring Boot Jar包转War包 部署到Tomcat下
原文:https://my.oschina.net/sdlvzg/blog/1562998 我们都知道springBoot中已经内置了tomcat,是不需要我们额外的配置tomcat服务器的,但是有时 ...
- python文本 字符串逐字符反转以及逐单词反转
python文本 字符串逐字符反转以及逐单词反转 场景: 字符串逐字符反转以及逐单词反转 首先来看字符串逐字符反转,由于python提供了非常有用的切片,所以只需要一句就可以搞定了 >>& ...
- Eclipse调试:改变颜色, 背景与字体大小 和xml字体调整
http://blog.csdn.net/qq272803220/article/details/7292699 eclipse操作界面默认颜色为白色.对于我们长期使用电脑编程的人来说,白色很刺激我们 ...