IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> getaddrinfo神秘面纱 -> 正文阅读

[网络协议]getaddrinfo神秘面纱

1. getaddrinfo能做什么

  • 名字到地址转换:解析DNS地址
  • 服务到端口转换:将IP地址和端口转换为一个socket地址

2. 重要数据结构

struct addrinfo {
    int              ai_flags;
    int              ai_family;
    int              ai_socktype;
    int              ai_protocol;
    socklen_t        ai_addrlen;
    struct sockaddr *ai_addr;
    char            *ai_canonname;
    struct addrinfo *ai_next;
};
  • ai_family
    • AF_INET:IPv4
    • AF_INET6:IPv6
    • AF_UNSPEC:协议无关
  • ai_protocol
    • IPPROTO_IP:IP协议
    • IPPROTO_IPV4:IPv4协议
    • IPPROTO_IPV6:IPv6协议
    • IPPROTO_UDP:UDP
    • IPPROTO_TCP:TCP
  • ai_socktype
    • SOCK_STREAM
    • SOCK_DGRAM
  • ai_flags
    • AI_PASSIVE:被动的,常用于bind和accept,用于server端
    • AI_CANONNAME:返回主机的规范名称
    • AI_NUMERICHOST:地址为数字

3. getaddrinfo原型

int getaddrinfo(const char *node, const char *service,
    const struct addrinfo *hints, struct addrinfo **res);
  • node可选值
    • 点分十进制IPv4地址
    • IPv6地址
    • DNS地址
      • 当node为DNS地址时,有时会遇到getaddrinfo返回过慢的问题,为什么?
        • 当getaddrinfo用来解析DNS时,底层实现使用res_nxxx系列接口(如:res_nsearch)
  • 影响getaddrinfo行为的hints.ai_flags
    • 当为AI_PASSIVE,node为NULL,server为一个端口,则返回一个0.0.0.0:port对应的socket地址,该地址可用于bind和accept
    • 当不设置AI_PASSIVE时,node不为NULL,则返回一个可用于connect、sendto或sendmsg的socket地址;如果node为NULL,则返回127.0.0.1的socket地址
  • service:设置socket地址对应的端口号。如果service为NULL,则端口默认被初始化为0
  • res:返回一个指向addrinfo结构体链表

注:node或service中任何一个可以为NULL,但不能两者都为NULL

4. 用例

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>

int main(int argc, const char *argv[])
{
    if (argc < 2) {
        fprintf(stderr, "Please input a valid address!\n");
        return -1;
    }

    char buffer[256] = {0};
    struct addrinfo hints = {0}, *result = NULL, *tmp = NULL;
    struct sockaddr_in *addr = NULL;
    struct sockaddr_in6 *addr6 = NULL;

    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_family = AF_INET;
    hints.ai_flags = 0;
    hints.ai_protocol = 0;

    int ret = getaddrinfo(argv[1], NULL, &hints, &result);
    if (ret) {
        fprintf(stderr, "errno: %d: %s\n", ret, gai_strerror(ret));
        return -1;
    }

    for (tmp = result; tmp; tmp = tmp->ai_next) {
        if (AF_INET == tmp->ai_family) {
            addr = (struct sockaddr_in*)tmp->ai_addr;
            printf("IPv4 Address: %s:%d\n", inet_ntop(AF_INET, &addr->sin_addr, buffer, sizeof(buffer)), htons(addr->sin_port));
        } else {
            addr6 = (struct sockaddr_in6*)tmp->ai_addr;
            printf("IPv6 Address: %s:%d\n", inet_ntop(AF_INET6, &addr6->sin6_addr, buffer, sizeof(buffer)), htons(addr6->sin6_port));
        }
    }
    freeaddrinfo(result);

    return 0;
}

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:32:18  更:2022-03-06 13:33:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:21:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码