addrinfo&sockaddr结构解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 介绍addrinfo、sockaddr结构体

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");
相关文章
|
2月前
|
存储 算法 安全
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
Java面试题:Java内存模型及相关知识点深度解析,Java虚拟机的内存结构及各部分作用,详解Java的垃圾回收机制,谈谈你对Java内存溢出(OutOfMemoryError)的理解?
45 0
|
9天前
|
数据采集 存储 JavaScript
如何使用Cheerio与jsdom解析复杂的HTML结构进行数据提取
在现代网页开发中,复杂的HTML结构给爬虫技术带来挑战。传统的解析库难以应对,而Cheerio和jsdom在Node.js环境下提供了强大工具。本文探讨如何在复杂HTML结构中精确提取数据,结合代理IP、cookie、user-agent设置及多线程技术,提升数据采集的效率和准确性。通过具体示例代码,展示如何使用Cheerio和jsdom解析HTML,并进行数据归类和统计。这种方法适用于处理大量分类数据的爬虫任务,帮助开发者轻松实现高效的数据提取。
如何使用Cheerio与jsdom解析复杂的HTML结构进行数据提取
|
26天前
|
存储 缓存 NoSQL
深入解析Memcached:内部机制、存储结构及在大数据中的应用
深入解析Memcached:内部机制、存储结构及在大数据中的应用
|
26天前
|
存储 缓存 算法
深入解析B树:数据结构、存储结构与算法优势
深入解析B树:数据结构、存储结构与算法优势
|
26天前
|
存储 监控 算法
深入解析JVM内部结构及GC机制的实战应用
深入解析JVM内部结构及GC机制的实战应用
|
2月前
|
数据采集 存储 XML
Ruby爬虫技术:深度解析Zhihu网页结构
Ruby爬虫技术:深度解析Zhihu网页结构
|
2月前
|
网络协议 安全 网络安全
解析IPv6报文结构
【7月更文挑战第1天】IPv6报文结构包括基本头和可选的扩展头,基本头固定40字节,含8个字段,不支持分片,提升了处理效率。扩展头灵活处理选项,长度为8字节的倍数,可包含如路由、分片、认证和安全封装等信息。多个扩展头按特定顺序排列,目的选项头可出现两次。
|
3月前
|
机器学习/深度学习 存储 算法
技术好文:ttf文件结构解析
技术好文:ttf文件结构解析
66 0
|
4月前
|
机器学习/深度学习 算法 Go
YOLOv5网络结构解析
YOLOv5网络结构解析
|
4月前
|
移动开发 HTML5
HTML基本结构标签解析
HTML基本结构标签解析
50 0

热门文章

最新文章

推荐镜像

更多