Chinaunix首页 | 论坛 | 博客
  • 博客访问: 361224
  • 博文数量: 161
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 345
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-13 11:04
文章分类

全部博文(161)

文章存档

2015年(15)

2014年(144)

2013年(2)

我的朋友

分类: 网络与安全

2014-12-26 09:38:32

最近使用socket编程, 用到这个函数。 网上资料很多,只是有一点没有提到,特记录下。

函数原型:

 int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
 void freeaddrinfo(struct addrinfo *res);

 

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;           

};

 

参数: node  即  主机名称 ,可以是主机名称字符串,比如“hostname",  也可以是IP地址的字符串,比如“ 192.169.1.1”  

    service 服务 即端口号   可以是一个服务的名称,比如"http", 也可以是一个数字字符串 ,比如“80” .

    hints    可以理解为约束条件,即 你创建的,要获得的addrinfo结构,有什么约束。 在hints中进行设置

    res     很明显,这个就是我们最终获得的addrinfo结构。

 

这个函数产生原因。 以前版本里面需要套接字编程,要得到sockaddr  类型: 必须使用两种函数  getserverbyname (一类的函数) 和  gethostent  (一类的函数), 然后构建 sockaddr_in 结构,在强制类型转换得到 sockaddr结构。 但是 getaddrinfo有了这个函数,这里过程就不用了,直接调用,就能得到 sockaddr 。 简化了编程过程。

注意点是: 这个函数,说起来,是get ,但是其实可以理解为creat 或者是理解为构建 。 因为你可以随意构建自己的地址结构addrinfo。

下面解释一下 hints 参数。 为什么要有这个参数 ? 

看一个小程序:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include
void main()

{        

struct addrinfo *ailist, *aip;        

struct addrinfo hint;        

struct sockaddr_in *sinp;       

 char *hostname = "luoyedeshan";          /*  这是我的用户名 */

char buf[INET_ADDRSTRLEN];        

char *server = "3294";                              /*  这是服务端口号 */

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)        

{               

 char str_error[100];                

strcpy(str_error,gai_strerror(errno));                

printf("str_error = %s", str_error);                

return;        

}

 

for (aip = ailist; aip != NULL; aip = aip->ai_next)                         /* 显示获取的信息  */

{                

sinp = (struct sockaddr_in *)aip->ai_addr;                                  /* 为什么是for 循环  ,先向下看 */

addr = inet_ntop(AF_INET, &sinp->sin_addr, buf, INET_ADDRSTRLEN);                

printf(" addr = %s", addr?addr:"unknow ");                

printf("port = %d ", ntohs(sinp->sin_port));                

printf(" \n");        

}

}
/*             执行结果如下                   */

[luoyedeshan@luoyedeshan wqr]$ ./a.out

addr = 0.0.0.0   port = 3294   

addr = 0.0.0.0    port = 3294   

addr = 0.0.0.0    port = 3294   

addr = 192.168.1.100   port = 3294   

addr = 192.168.1.100   port = 3294   

addr = 192.168.1.100   port = 3294 

 

细心的你,也许发现,为什么重复了3次, 0.0.0.0  是本地地址,没话说, 192.168.1.100是局域网地址, 也没什么,为什么会得到3个重复的呢?? 

这就是 hint的作用,源代码里面我没甚至什么,hint都为空,所有有3个。 你在hint设置了,就可以屏蔽掉一些对你没用的addrinfo结构.   虽然有三个,他们的IP地址和端口号都一样,但是  这三个套接字类型不一样。  我试过 ,分别为 下面三种套接字类型   SOCK_DGRAM    SOCK_SEQPACKET   SOCK_STREAM .

 

把上面的 ai_socktype  改为 SOCK_STREAM  就只显示一个了。

 

关于这个函数的具体在套接字应用,在网上很多都有了,随便找一个试试,就可以了,这里就不给代码了。

阅读(2956) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~