addrinfo& sockaddr结构解析

来源:互联网 发布:建筑工程软件有哪些 编辑:程序博客网 时间:2024/06/05 05:57

1 addrinfo

addrinfo结构内容如下:

struct addrinfo {    int ai_flags;   /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */    int ai_family;  /* PF_xxx */    int ai_socktype;    /* SOCK_xxx */    int ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */    socklen_t ai_addrlen;   /* length of ai_addr */    char    *ai_canonname;  /* canonical name for hostname */    struct  sockaddr *ai_addr;  /* binary address */    struct  addrinfo *ai_next;  /* next structure in linked list */};

1.1 ai_family

ai_family指定了地址族,可取值如下:

值 取值 含义 AF_INET 2 IPv4 AF_INET6 23 IPv6 AF_UNSPEC 0 协议无关
void print_family(struct addrinfo *aip){    printf(" family ");    switch (aip->ai_family) {    case AF_INET:        printf("inet");        break;T    case AF_INET6:        printf("inet6");        break;    case AF_UNIX:        printf("unix");        break;    case AF_UNSPEC:        printf("unspecified");        break;    default:        printf("unknown");    }}

1.2 ai_socketype

值 取值 含义 SOCK_STREAM 1 数据流协议 SOCK_DGRAM 2 数据报协议
void print_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);    }}

1.3 ai_protocol

值 取值 含义 IPPROTO_IP 0 IP协议 IPPROTO_IPV4 4 IPv4 IPPROTO_IPV6 41 IPv6 IPPROTO_UDP 17 UDP IPPROTO_TCP 6 TCP
void print_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);    }}

1.4 ai_flags

值 取值 含义 AI_PASSIVE 1 被动的,用于bind,通常用于server socket AI_CANONNAME 2 用于返回主机的规范名称 AI_NUMERICHOST 4 地址为数字串
void print_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    }}

1.5 sockaddr

套接字体制二级制表示。详见第2节。

2. sockaddr & sockaddr_in

sockaddr:

struct sockaddr {    unsigned  short  sa_family;     /* address family, AF_xxx */    char  sa_data[14];                 /* 14 bytes of protocol address */};
  • sa_family是地址家族,一般都是“AF_xxx”的形式。好像通常大多用的是都是AF_INET
  • sa_data是14字节协议地址

此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。但一般编程中并不直接针对此数据结构操作,而是使用另一个与sockaddr等价的数据结构:sockaddr_in:

// sockaddr_in(在netinet/in.h中定义):struct  sockaddr_in {  short  int  sin_family;                      /* Address family */  unsigned  short  int  sin_port;       /* Port number */  struct  in_addr  sin_addr;              /* Internet address */  unsigned  char  sin_zero[8];         /* Same size as struct sockaddr */};struct in_addr {  __be32 s_addr;};
  • sin_family指代协议族,在socket编程中只能是AF_INET
  • sin_port存储端口号(使用网络字节顺序)
  • sin_addr存储IP地址,使用in_addr这个数据结构,sin_addr按照网络字节顺序存储IP地址
  • sin_zero是为了让sockaddrsockaddr_in两个数据结构保持大小相同而保留的空字节。

sockaddr_insockaddr是并列的结构,指向sockaddr_in的结构体的指针也可以指向
sockadd的结构体,并代替它。也就是说,你可以使用sockaddr_in建立你所需要的信息,
在最后用进行类型转换就可以了bzero((char*)&mysock,sizeof(mysock));

//初始化:mysock; // 结构体名mysock.sa_family=AF_INET;mysock.sin_addr.s_addr=inet_addr("192.168.0.1");
原创粉丝点击