lib-zo,C语言另一个协程库,dns协程化, gethostbyname

news2025/4/14 8:45:18

lib-zo,C语言另一个协程库,dns协程化, gethostbyname

另一个 C 协程库 https://blog.csdn.net/eli960/article/details/146802313

本协程库 支持 DNS查询 协程化.

禁用所有 UDP 协程化

zvar_coroutine_disable_udp = 1;

禁用 53 端口的UDP 协程化

zvar_coroutine_disable_udp_53 = 1;

例子

// 包含协程相关的头文件
#include "coroutine.h"

// 包含解析器相关的头文件
#include <resolv.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// 定义并发实例的数量
static int instances = 10;
// 定义测试类型
static int test_type = 0;

/**
 * @brief 执行域名查询测试的协程函数
 * 
 * @param arg 传入的参数,为要查询的域名
 * @return void* 总是返回 0
 */
static void *foo(void *arg)
{
    // 将参数转换为字符串类型,即要查询的域名
    const char *name = (char *)arg;
    // 用于存储 DNS 查询结果的缓冲区
    char answer[1024+1];
#ifdef res_nquery
    // 定义解析器状态结构体
    struct __res_state state;
    // 如果测试类型为 2,则初始化解析器状态
    if (test_type == 2) {
        res_ninit(&state);
    }
#endif

    // 循环执行 10 次查询操作
    for (int i = 0; i < 10; i++) {
        // 在第 3 次和第 6 次循环时暂停 1 秒
        if ((i == 3) || (i == 6)) {
            sleep(1);
        }
        // 如果测试类型为 0,使用 gethostbyname 进行查询
        if (test_type == 0) {
            // 调用 gethostbyname 函数进行域名查询
            struct hostent *hp = gethostbyname(name);
            if (hp) {
                // 查询成功,打印域名及其官方名称
                printf("%s: %s\n", name, hp->h_name);
            } else {
                // 查询失败,打印未找到信息
                printf("%s: not found\n", name);
            }
        }
        // 如果测试类型为 1,使用 res_query 进行查询
        if (test_type == 1) {
            // 调用 res_query 函数进行 DNS 查询
            int ret = res_query(name, C_IN, T_A, (unsigned char *)answer, 1024);
            // 打印查询结果
            printf("res_query %s: %d\n", name, ret);
        }
#ifdef res_nquery
        // 如果测试类型为 2,使用 res_nquery 进行查询
        if (test_type == 2) {
            // 调用 res_nquery 函数进行 DNS 查询
            int ret = __res_nquery(&state, name, C_IN, T_A, (unsigned char *)answer, 1024);
            // 打印查询结果
            printf("res_nquery %s: %d\n", name, ret);
        }
#endif
    }
#ifdef res_nquery
    // 如果测试类型为 2,关闭解析器状态
    if (test_type == 2) {
        res_nclose(&state);
    }
#endif
    // 完成一个实例的查询,实例数量减 1
    instances--;
    return 0;
}

/**
 * @brief 监控实例数量,当所有实例完成后通知协程停止的函数
 * 
 * @param arg 传入的参数,未使用
 * @return void* 总是返回 0
 */
static void *foo2(void *arg) 
{
    // 当还有未完成的实例时,持续等待
    while(instances) {
        sleep(1);
    }
    // 所有实例完成后,再等待 1 秒
    sleep(1);
    // 通知协程基础框架停止运行
    zcoroutine_base_stop_notify(0);
    return 0;
}

/**
 * @brief 初始化函数,处理命令行参数并输出使用说明
 * 
 * @param argc 命令行参数的数量
 * @param argv 命令行参数数组
 * @return int 初始化成功返回 1,失败返回 0
 */
static int _init(int argc, char **argv)
{
    // 输出程序的使用说明
    printf("USAGE: \n%s domain1 domain2 [ test_type ] [ disable_udp]\n", argv[0]);
    printf("  test_type:\n");
    printf("    0\t\t # gethostbyname(default)\n");
    printf("    1\t\t # res_query\n");
#ifdef res_nquery
    printf("    2\t\t # res_nquery\n");
#else
    printf("    2\t\t # res_nquery, unsupported\n");
#endif
    printf("  disable_udp:\n");
    printf("    udp\t\t # disable all udp coroutine swap\n");
    printf("    53\t\t # disable udp(53) coroutine swap\n");

    // 如果命令行参数少于 3 个,说明输入不完整,返回 0
    if (argc < 3) {
        return 0;
    }

    printf("\n");
    // 标记是否显示了测试类型信息
    int type_show = 0;
    // 处理第 3 个及以后的命令行参数
    for (int i = 3; i < argc; i++) {
        const char *s = argv[i];
        if (!strcmp(s, "0")) {
            // 测试类型为 0,使用 gethostbyname 进行查询
            printf("######## test gethostbyname\n");
            type_show = 1;
            test_type = 0;
        } else if (!strcmp(s, "1")) {
            // 测试类型为 1,使用 res_query 进行查询
            printf("######## test req_query\n");
            type_show = 1;
            test_type = 1;
        } else if (!strcmp(s, "2")) {
            // 测试类型为 2,使用 res_nquery 进行查询
            printf("######## test req_nquery\n");
            type_show = 1;
            test_type = 2;
        } else if (!strcmp(s, "udp")) {
            // 禁用所有 UDP 协程交换
            zvar_coroutine_disable_udp = 1;
            printf("######## disable all udp\n");
        } else if (!strcmp(s, "53")) {
            // 禁用 UDP 端口 53 的协程交换
            zvar_coroutine_disable_udp_53 = 1;
            printf("######## disable udp(53)\n");
        } else {
            // 未知参数,输出提示信息
            printf("######## unknown %s\n", s);
        }
    }
    // 如果未指定测试类型,使用默认的 gethostbyname 测试
    if (type_show == 0) {
        printf("######## test gethostbyname, default\n");
    }
#ifndef res_nquery
    // 如果系统不支持 res_nquery,输出提示信息
    printf("######## res_nquery unsupported in your system\n");
#endif
    printf("\n");
    return 1;
}

/**
 * @brief 程序入口函数
 * 
 * @param argc 命令行参数的数量
 * @param argv 命令行参数数组
 * @return int 程序退出状态码
 */
int main(int argc, char **argv)
{
    // 调用初始化函数,如果初始化失败,直接返回 0
    if (_init(argc, argv) == 0) {
        return 0;
    }
    // 初始化协程基础框架
    zcoroutine_base_init();
    // 创建协程进行域名查询
    for (int i = 0; i < instances/2; i++) {
        zcoroutine_go(foo, argv[1], 0);
        zcoroutine_go(foo, argv[2], 0);
    }
    // 创建监控协程
    zcoroutine_go(foo2, 0, 0);
    // 启动协程基础框架运行
    zcoroutine_base_run();
    // 销毁协程基础框架
    zcoroutine_base_fini();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2327669.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

强化学习_Paper_1988_Learning to predict by the methods of temporal differences

paper Link: sci-hub: Learning to predict by the methods of temporal differences 1. 摘要 论文介绍了时间差分方法&#xff08;TD 方法&#xff09;&#xff0c;这是一种用于预测问题的增量学习方法。TD 方法通过比较连续时间步的预测值之间的差异来调整模型&#xff0c;…

Apache httpclient okhttp

学习链接 okhttp github okhttp官方使用文档 SpringBoot 整合okHttp okhttp3用法 Java中常用的HTTP客户端库&#xff1a;OkHttp和HttpClient&#xff08;包含请求示例代码&#xff09; 深入浅出 OkHttp 源码解析及应用实践 httpcomponents-client github apache httpclie…

Docker部署Blinko:打造你的个性化AI笔记助手与随时随地访问

文章目录 前言1. Docker Compose一键安装2. 简单使用演示3. 安装cpolar内网穿透4. 配置公网地址5. 配置固定公网地址 前言 嘿&#xff0c;小伙伴们&#xff0c;是不是觉得市面上那些单调乏味的笔记应用让人提不起劲&#xff1f;今天&#xff0c;我要给大家安利一个超炫酷的开源…

【文献研究】铝对热冲压加热过程中锌氧化的影响

在热冲压过程中&#xff0c;镀锌铁板和镀锌板等镀锌钢板表面发生Zn氧化。为了阐明镀锌层中的Al对Zn氧化的影响&#xff0c;本研究研究了镀锌钢板上添加和不添加Al时形成的ZnO量。发现添加铝后ZnO量减少。对添加铝的镀锌钢板的显微组织分析表明&#xff0c;添加的Al在热冲压后Zn…

Win11本地从零开始部署dify全流程

1.安装wsl和打开Hyper-V功能&#xff08;前置准备&#xff09; 这个是为了支持我们的Docker Desktop运行。 1.1.安装wsl 使用管理员身份运行命令行。 如果显示 “无法与服务器建立连接就执行“&#xff0c;表示没有安装wsl&#xff0c;如果更新成功&#xff0c;那就不用执行…

【HTB】Windwos-easy-Legacy靶机渗透

靶机介绍&#xff0c;一台很简单的WIndows靶机入门 知识点 msfconsole利用 SMB历史漏洞利用 WIndows命令使用&#xff0c;type查看命令 目录标题 一、信息收集二、边界突破三、权限提升 一、信息收集 靶机ip&#xff1a;10.10.10.4攻击机ip&#xff1a;10.10.16.26 扫描TC…

蓝桥杯真题———k倍区间

题目如下 代码如下 记录余数 cnt[0] 1 的初始化是为了处理 空前缀和 说明

无人机等非合作目标公开数据集2025.4.3

一.无人机遥感数据概述 1.1 定义与特点 在遥感技术的不断发展中&#xff0c;无人机遥感数据作为一种新兴的数据源&#xff0c;正逐渐崭露头角。它是通过无人驾驶飞行器&#xff08;UAV&#xff09;搭载各种传感器获取的地理空间信息&#xff0c;具有 覆盖范围大、综合精度高、…

机器视觉--python基础语法

Python基础语法 1. Python标识符 在 Python 里&#xff0c;标识符由字母、数字、下划线组成。 在 Python 中&#xff0c;所有标识符可以包括英文、数字以及下划线(_)&#xff0c;但不能以数字开头。 Python 中的标识符是区分大小写的。 以下划线开头的标识符是有特殊意义的…

司南评测集社区 3 月上新一览!

司南评测集社区 CompassHub 作为司南评测体系的重要组成部分&#xff0c;旨在打创新性的基准测试资源导航社区&#xff0c;提供丰富、及时、专业的评测集信息&#xff0c;帮助研究人员和行业人士快速搜索和使用评测集。 2025 年 3 月&#xff0c;司南评测集社区新收录了一批评…

mac环境中Nginx安装使用 反向代理

安装 如没有Homebrew 先安装Homebrew 国内镜像&#xff1a; /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 安装成功后安装nginx&#xff1a; brew install nginx 启动nginx&#xff1a; nginx 或者 brew services st…

实战打靶集锦-36-Deception

文章目录 1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查5. 系统提权6. 写在最后 靶机地址&#xff1a;https://download.vulnhub.com/haclabs/Deception.ova 1. 主机发现 目前只知道目标靶机在192.168.56.xx网段&#xff0c;通过如下的命令&#xff0c;看看这个网段上在线的主…

前端开发技术演进与就业现实:顺应时代方能不被淘汰-优雅草卓伊凡

前端开发技术演进与就业现实&#xff1a;顺应时代方能不被淘汰-优雅草卓伊凡 在技术浪潮汹涌的当下&#xff0c;常有人发问&#xff1a;“学习CSS、HTML、JS以后可以干什么&#xff1f;”对此&#xff0c;卓伊凡可以明确地给出答案&#xff1a;单纯学习这些过于基础的Web前端开…

敏捷开发:以人为本的高效开发模式

目录 前言1. 什么是敏捷开发&#xff1f;1.1 敏捷开发的核心理念1.2 敏捷开发的优势 2. 敏捷宣言&#xff1a;四大核心价值观2.1 个体和交互胜过工具和过程2.2 可工作的软件胜过大量的文档2.3 客户合作胜过合同谈判2.4 响应变化胜过遵循计划 3. 敏捷开发的实践3.1 Scrum&#x…

CAD插入属性块 弹窗提示输入属性值——CAD知识讲堂

插入属性块时&#xff0c;有时会遇到不弹窗输入属性值的情况&#xff0c;解决方案如下&#xff1a; 最好关闭块编辑器并保存&#xff0c;插入属性块即可弹窗。

Sentinel实战(三)、流控规则之流控效果及流控小结

spring cloud Alibaba-Sentinel实战&#xff08;三&#xff09;、流控效果流控小结 一、流控规则&#xff1a;流控效果一&#xff09;、流控效果&#xff1a;预热1、概念含义2、案例流控规则设置测试结果 二&#xff09;、流控效果&#xff1a;排队等待1、概念含义2、案例流控规…

PP-ChatOCRv3新升级:多页PDF信息抽取支持自定义提示词工程,拓展大语言模型功能边界

文本图像信息抽取技术在自动化办公、建筑工程、教育科研、金融风控、医疗健康等行业领域具有广泛应用场景。2024年9月&#xff0c;飞桨低代码开发工具PaddleX中新增文本图像智能产线PP-ChatOCRv3&#xff0c;充分结合PaddleOCR的文本图像版面解析能力和文心一言语言理解优势&am…

《二叉树:二叉树的顺序结构->堆》

二叉树一般可以使用两种结构存储&#xff0c;一种是顺序结构&#xff0c;一种是链式结构。 顺序存储 顺序结构存储是使用数组来存储&#xff0c;一般使用数组只适合表示完全二叉树&#xff0c;因为不是完全二叉树会有空间的浪费。实际上使用中只有堆才会使用数组来存储。二叉…

OpenLayers:封装Overlay的方法

平时在使用OpenLayers的Overlay时常感觉不便&#xff0c;于是最近我便封装了一些Overlay增删改查的方法&#xff0c;以提高可用性。这边文章中我会介绍我封装的方法&#xff0c;同时记录这个过程中踩的一些坑。 添加Overlay /*** abstract 添加overlay* param {*} map* param…

软件重构与项目进度的矛盾如何解决

软件重构与项目进度之间的矛盾可以通过明确重构目标与范围、采用渐进式重构策略、优化项目管理流程、提高团队沟通效率、建立重构意识文化等方式解决。其中&#xff0c;采用渐进式重构策略尤为关键。渐进式重构是指在日常开发过程中&#xff0c;以小步骤持续进行重构&#xff0…