`

Addrinfo and Getaddrinfo (网络编程)

阅读更多

转载:http://woxihuanpes.blog.163.com/blog/static/124232198200972791254865/

 

 

gethostbyname和gethostbyaddr这两个函数仅仅支持IPv4,getaddrinfo函数能够处理名字到地址以及服务到端口这两 种转换,返回的是一个sockaddr结构的链表而不是一个地址清单。这些sockaddr结构随后可由套接口函数直接使用。如此以 来,getaddrinfo函数把协议相关性安全隐藏在这个库函数内部。应用程序只要处理由getaddrinfo函数填写的套接口地址结构。该函数在 POSIX规范中定义了。

#include<netdb.h>
int getaddrinfo( const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result );
返回0:  成功
返回非0:  出错

hostname:一个主机名或者地址串(IPv4的点分十进制串或者IPv6的16进制串)
service:一个服务名或者10进制端口号数串。
hints: 可以是一个空指针,也可以是一个指向某个addrinfo结构的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。举例来说:如果指定的服务既 支持TCP也支持UDP,那么调用者可以把hints结构中的ai_socktype成员设置成SOCK_DGRAM使得返回的仅仅是适用于数据报套接口 的信息。

本函数通过result指针参数返回一个指向addrinfo结构链表的指针,而addrinfo结构定义在头文件netdb.h中:
struct addrinfo{
    int       ai_flags;  
    int       ai_family;
    int       ai_socktype;
    int       ai_protocol;
    socklen_t ai_addrlen;
    char    *ai_canonname;
    struct sockaddr *ai_addr;
    struct addrinfo *ai_next;
};

如果本函数返回成功,那么由result参数指向的变量已被填入一个指针,它指向的是由其中的ai_next成员串联起来的addrinfo结构链表。可以导致返回多个addrinfo结构的情形有以下2个:
    1.    如果与hostname参数关联的地址有多个,那么适用于所请求地址簇的每个地址都返回一个对应的结构。
    2.    如果service参数指定的服务支持多个套接口类型,那么每个套接口类型都可能返回一个对应的结构,具体取决于hints结构的ai_socktype成员。

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

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

其中,如果getaddrinfo出错,那么返回一个非0的错误值。

#include<netdb.h>
const char *gai_strerror( int error );
该函数以getaddrinfo返回的非0错误值的名字和含义为他的唯一参数,返回一个指向对应的出错信息串的指针。

由getaddrinfo返回的所有存储空间都是动态获取的,这些存储空间必须通过调用freeaddrinfo返回给系统。
#include< netdb.h >
void freeaddrinfo( struct addrinfo *ai );

ai参数应指向由getaddrinfo返回的第一个addrinfo结构。这个连表中的所有结构以及它们指向的任何动态存储空间都被释放掉。


例子:
struct addrinfo *host_serv( const char *host, const char *serv, int family, int socktype )
{
    int n;
    struct   addrinfo  hints,  *res;

    bzero( &hints, sizeof(struct addrinfo) );
    hints.ai_flags = AI_CANONNAME;
    hints.ai_family = family;
    hints.ai_socktype = socktype;

    if( (n = getaddrinfo( host, serv, &hints, &res ) ) != 0 )
       return (NULL);

    return ( res );
}

 

 

分享到:
评论

相关推荐

    UNIX Network Programming Volume 1, Third Edition (Unix网络编程卷1第3版英文版)

    Unix网络编程卷1,第三版,英文版。大名顶顶的Richard Stevens所写 目录: Copyright Addison-Wesley Professional Computing Series Foreword Preface Introduction Changes from the Second Edition ...

    如何用C++编程获得某台机器的IP地址

    这里我们将主要介绍两种方法:使用`gethostbyname`函数(适用于较旧的系统)和使用`getaddrinfo`函数(适用于现代系统)。 1. **使用`gethostbyname`函数** `gethostbyname`是源自BSD系统的函数,它可以从主机名中...

    NAME-AND-IP-switch.zip_网络编程_Visual_C++_

    标题中的"NAME-AND-IP-switch.zip"是一个与网络编程相关的项目,主要涉及在Visual C++环境下实现名字到IP地址的转换。这个压缩包可能包含一个名为"NAME AND IP switch.doc"的文档,该文档详细介绍了项目的实现过程、...

    get-the-host-name-and-IP.zip_网络编程_Visual_C++_

    `gethostbyname()`适用于较旧的系统,`getaddrinfo()`则是更现代且推荐的方法,因为它支持IPv6: ```cpp struct hostent *host_entry; host_entry = gethostbyname(hostname); if (host_entry == NULL) { // 错误...

    Data Communication and Networking, C++, socket

    在C++中,可以使用`gethostbyname()`或`getaddrinfo()`函数获取主机信息,包括其IP地址。 文件名为"5.24 Version2"可能指的是项目的某个迭代版本,这通常包含了代码的更新和改进。在实际开发中,版本控制工具如Git...

    Visual.C.程序开发范例宝典 通过家算计名获取IP

    其中,`GetComputerName`函数用于获取当前计算机的名称,而`gethostbyname`或`getaddrinfo`函数则可以用来根据计算机名解析出IP地址。 1. `GetComputerName`: 这个函数接受一个缓冲区和一个大小参数,用于存储...

    获取主机名和IP地址

    总结来说,获取主机名和IP地址涉及对操作系统底层网络服务的理解和使用,包括调用适当的系统函数,如`gethostname`、`getaddrinfo`等,并处理可能的错误情况。VC++范例大全中的例子源代码程序提供了实践这些概念的...

    信息网络与协议课程实验

    同时,他们还需要了解如何使用`getaddrinfo()`和`getnameinfo()`函数解析和格式化IPv6地址。 实验3则可能涉及到IPv6的扩展报头,如分片和重组、流标签和优先级等高级特性。此外,可能会涉及ICMPv6(Internet ...

    通过ip查询地址,c++程序

    在C++中,我们可以使用`gethostbyname`函数(在`&lt;netdb.h&gt;`头文件中定义)或更现代的`getaddrinfo`函数(在`&lt;sys/socket.h&gt;`和`&lt;netdb.h&gt;`头文件中定义)来实现这个功能。`gethostbyname`已经被标记为过时,但仍然在...

    获取本机网卡信息(包括ipv6 地址信息)

    这段代码使用了Winsock2 API的`getaddrinfo`函数,它可以获取主机的地址信息。注意,由于我们关心的是IPv6地址,所以检查`ai_family`为AF_INET6。 在程序开发中,`hh.cpp`可能是实现上述功能的源代码文件,而`.dsp`...

    C++ Scoket实现Client获取本机计算机名和ip地址发送到Server

    - **获取本机信息**:在C++中,可以使用`gethostname()`函数获取计算机名,`gethostbyname()`或`getaddrinfo()`获取IP地址。 - **发送数据**:客户端将获取到的计算机名和IP地址打包成字符串,然后使用send()发送...

    network-and-communication-codes

    2. **地址解析和封装**:使用`getaddrinfo()`和`inet_ntop()`函数进行IP地址和端口号的解析和转换。 3. **数据传输**:`send()`和`recv()`函数用于发送和接收数据。为了提高效率,通常会结合使用缓冲区和非阻塞I/O...

    Socket Programming in C

    `getnameinfo()`和`getaddrinfo()`函数用于获取主机名和地址信息,`getname.c`和`getaddr.c`可能是这两个函数的实现或使用示例。 10. **文档参考**: `Socket Programming in C.doc`可能包含更详细的理论介绍、...

    VC++自动搜索IP地址

    `getaddrinfo()`函数通过结构体`addrinfo`返回一个链表,包含了关于目标主机的各种网络地址信息。 以下是一个简化的示例,演示如何在VC++中使用MFC获取IP地址: ```cpp #include #include #include #pragma ...

    python服务器与android客户端socket通信实例

    本文实例讲述了python服务器与android客户端socket通信的方法。... result = socket.getaddrinfo(hostname, None, 0, socket.SOCK_STREAM)   return [x[4][0] for x in result]    host = ”#为空

Global site tag (gtag.js) - Google Analytics