socket编程之addrinfo结构体与getaddrinfo函数
来源:互联网 发布:网络部招新面试问题 编辑:程序博客网 时间:2024/06/06 00:48
原文地址 http://blog.chinaunix.net/uid-26583794-id-3167485.html
addrinfo结构体的定义如下:
struct addrinfo { int ai_flags; /* customize behavior */ int ai_family; /* address family */ int ai_socktype; /* socket type */ int ai_protocol; /* protocol */ socklen_t ai_addrlen; /* length in bytes of address */ struct sockaddr *ai_addr; /* address */ char *ai_canonname; /* canonical name of host */ struct addrinfo *ai_next; /* next in list */ . . . };
ai_family指定了地址族,可取值如下:
AF_INET 2 IPv4
AF_INET6 10 IPv6
AF_UNSPEC 0 协议无关
ai_socktype指定我套接字的类型
SOCK_STREAM 1 流
SOCK_DGRAM 2 数据报
在AF_INET通信域中套接字类型SOCK_STREAM的默认协议是TCP(传输控制协议)
在AF_INET通信域中套接字类型SOCK_DGRAM的默认协议是UDP(用户数据报协议)
ai_protocol指定协议类型。可取的值取决于ai_address和ai_socktype的值
ai_flags指定了如何来处理地址和名字,可取值如下:
getaddrinfo函数 定义及需要的头文件如下
#include <sys/socket.h>#include <netdb.h>int getaddrinfo(const char *restrict host, const char *restrict service, const struct addrinfo *restrict hint, struct addrinfo **restrict res);Returns: 0 if OK, nonzero error code on errorvoid freeaddrinfo(struct addrinfo *ai);
getaddrinfo函数允许将一个主机名字和服务名字映射到一个地址。
使用示例如下:
#include<stdio.h>#include<stdlib.h>#include <netdb.h>#include <arpa/inet.h>voidprint_family(struct addrinfo *aip){ printf(" family "); switch (aip->ai_family) { case AF_INET: printf("inet"); break; case AF_INET6: printf("inet6"); break; case AF_UNIX: printf("unix"); break; case AF_UNSPEC: printf("unspecified"); break; default: printf("unknown"); }}voidprint_type(struct addrinfo *aip){ printf(" type "); switch (aip->ai_socktype) { case SOCK_STREAM: printf("stream"); break; case SOCK_DGRAM: printf("datagram"); break; case SOCK_SEQPACKET: printf("seqpacket"); break; case SOCK_RAW: printf("raw"); break; default: printf("unknown (%d)", aip->ai_socktype); }}voidprint_protocol(struct addrinfo *aip){ printf(" protocol "); switch (aip->ai_protocol) { case 0: printf("default"); break; case IPPROTO_TCP: printf("TCP"); break; case IPPROTO_UDP: printf("UDP"); break; case IPPROTO_RAW: printf("raw"); break; default: printf("unknown (%d)", aip->ai_protocol); }}voidprint_flags(struct addrinfo *aip){ printf("flags"); if (aip->ai_flags == 0) { printf(" 0"); } else { if (aip->ai_flags & AI_PASSIVE) printf(" passive"); if (aip->ai_flags & AI_CANONNAME) printf(" canon"); if (aip->ai_flags & AI_NUMERICHOST) printf(" numhost");#if defined(AI_NUMERICSERV) if (aip->ai_flags & AI_NUMERICSERV) printf(" numserv");#endif#if defined(AI_V4MAPPED) if (aip->ai_flags & AI_V4MAPPED) printf(" v4mapped");#endif#if defined(AI_ALL) if (aip->ai_flags & AI_ALL) printf(" all");#endif }}intmain(int argc, char *argv[]){ struct addrinfo *ailist, *aip; struct addrinfo hint; struct sockaddr_in *sinp; const char *addr; int err; char abuf[INET_ADDRSTRLEN]; if (argc != 3) printf("usage: %s nodename service", argv[0]); hint.ai_flags = AI_CANONNAME; hint.ai_family = 0; hint.ai_socktype = 0; hint.ai_protocol = 0; hint.ai_addrlen = 0; hint.ai_canonname = NULL; hint.ai_addr = NULL; hint.ai_next = NULL; if ((err = getaddrinfo(argv[1], argv[2], &hint, &ailist)) != 0) printf("getaddrinfo error: %s", gai_strerror(err)); for (aip = ailist; aip != NULL; aip = aip->ai_next) { print_flags(aip); print_family(aip); print_type(aip); print_protocol(aip); printf("\n\thost %s", aip->ai_canonname?aip->ai_canonname:"-"); if (aip->ai_family == AF_INET) { sinp = (struct sockaddr_in *)aip->ai_addr; addr = inet_ntop(AF_INET, &sinp->sin_addr, abuf,INET_ADDRSTRLEN); printf(" address %s", addr?addr:"unknown"); printf(" port %d", ntohs(sinp->sin_port)); } printf("\n"); } exit(0);}
代码说明:
sinp = (struct sockaddr_in *)aip->ai_addr;会将struct sockaddr 变量强制转化为struct sockaddr_in 类型
inet_ntop函数用于在二进制格式与点分十进制格式表示(a.b.c.d)之间进行转换
执行结果:
root@X86-PC:/home# ./a X86-PC nfs
flags canon family inet type stream protocol TCP
host X86-PC address 127.0.1.1 port 2049
flags canon family inet type datagram protocol UDP
host - address 127.0.1.1 port 2049
root@X86-PC:/home#
- socket编程之addrinfo结构体与getaddrinfo函数
- socket编程之addrinfo结构体与getaddrinfo函数
- socket编程之addrinfo结构体与getaddrinfo函数
- socket编程之addrinfo结构体与getaddrinfo函数
- socket编程之addrinfo结构体与getaddrinfo函数
- socket编程之addrinfo结构体与getaddrinfo函数
- socket编程之addrinfo结构体与getaddrinfo函数
- socket编程之addrinfo结构体与getaddrinfo函数
- socket编程之addrinfo结构体与getaddrinfo函数
- socket编程之addrinfo结构体与getaddrinfo函数
- socket编程之addrinfo结构体与getaddrinfo函数
- addrinfo结构体与getaddrinfo函数
- addrinfo结构体与getaddrinfo函数
- Linux 编程 之 【socket】 getaddrinfo
- socket编程总结(三) struct sockaddr_in /struct sockaddr_in6/struct addrinfo 结构体
- socket编程总结(一)getaddrinfo()函数详解
- addrinfo结构体详解
- struct addrinfo结构体
- 页面调度算法 FIFO,LRU,OPT,及C++代码
- iOS - 页面之间传值的实现 - block
- Android6.0手机权限处理工具类
- ElementUI案例演示:导航、布局、加载动画
- 如何在Android智能手机上捕获数据包?
- socket编程之addrinfo结构体与getaddrinfo函数
- 占楼
- 初涉python,用户登录功能
- MyBatis入门——动态SQL
- 工作中常常使用的几种加密以及签名的方式:Base64
- iOS UITabelView 头视图跟随移动的设置
- Qt实现网络数据传输(POST)
- 感知机的对偶形式实现java版
- 编写junit单元测试