使用c-ares和libcurl [英] using c-ares and libcurl

查看:207
本文介绍了使用c-ares和libcurl的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include 
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include 
#include <string.h>
#include <assert.h>

#define ERROR_EXIT(x...) do {fprintf(stderr, x);fprintf(stderr, ", %s:%d", __FILE__, __LINE__);exit(-1);}while(0)
#define DEBUG(x...) do {fprintf(stdout, x);}while(0)
#define ERROR(x...) do {fprintf(stderr, x);fprintf(stderr, ", %s:%d", __FILE__, __LINE__);}while(0)

CURLM *multi_handle = NULL;
int epoll_fd = -1;
int still_running;

static void mcode_or_die(const char *where, CURLMcode code) {
    if ( CURLM_OK != code ) { 
        const char *s; 
        switch (code) {
            case     CURLM_CALL_MULTI_PERFORM: s="CURLM_CALL_MULTI_PERFORM"; break;
            case     CURLM_BAD_HANDLE:         s="CURLM_BAD_HANDLE";         break;
            case     CURLM_BAD_EASY_HANDLE:    s="CURLM_BAD_EASY_HANDLE";    break;
            case     CURLM_OUT_OF_MEMORY:      s="CURLM_OUT_OF_MEMORY";      break;
            case     CURLM_INTERNAL_ERROR:     s="CURLM_INTERNAL_ERROR";     break;
            case     CURLM_UNKNOWN_OPTION:     s="CURLM_UNKNOWN_OPTION";     break;
            case     CURLM_LAST:               s="CURLM_LAST";               break;
            default:                           s="CURLM_unknown";            break;
            case     CURLM_BAD_SOCKET:         s="CURLM_BAD_SOCKET";
                                               ERROR("ERROR: %s returns %s\n", where, s); 
                                               /* ignore this error */
                                               return;
        }
        ERROR("ERROR: %s returns %s\n", where, s); 
        exit(code);
    }
    else {
        // DEBUG("INFO: %s returns OK\n", where); 
    }
}

static void check_multi_info() {
    char *eff_url;

    CURLcode res;
    int msgs_left;
    CURLMsg *msg;
    CURL *easy;

    while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
        if (msg->msg == CURLMSG_DONE) {
            easy = msg->easy_handle;
            res = msg->data.result;
            curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
            DEBUG("DONE: %s => (%d)\n", eff_url, res);
            curl_multi_remove_handle(multi_handle, easy);
            curl_easy_cleanup(easy);
        }
    }
}
/*
static int multi_timer_cb(CURLM *multi, long timeout_ms, void *g) {
    DEBUG("multi_timer_cb\n");
    DEBUG("multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
    CURLMcode rc = curl_multi_socket_action(multi_handle, CURL_SOCKET_TIMEOUT, 0, &still_running);
    mcode_or_die("multi_timer_cb", rc);
    check_multi_info();
    return 0;
}
*/
static int multi_socket_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) {
    DEBUG("multi_socket_cb--------------------------------------------------------------%p\n", sockp);

    struct epoll_event ee;
    ee.data.fd = s;

    switch ( what ) {
        case CURL_POLL_REMOVE:
            epoll_ctl(epoll_fd, EPOLL_CTL_DEL, s, NULL);
            DEBUG("---->>>>finish%p\n", sockp);
            // clean
            return 0;

        case CURL_POLL_IN:
            ee.events = EPOLLIN;
            DEBUG("---->>>>EPOLLIN%p\n", sockp);
        epoll_ctl(epoll_fd, EPOLL_CTL_MOD, s, &ee);
            break;
        case CURL_POLL_OUT:
            ee.events = EPOLLOUT;
        epoll_ctl(epoll_fd, EPOLL_CTL_ADD, s, &ee);
            DEBUG("---->>>>EPOLLOUT%p\n", sockp);
            break;
        case CURL_POLL_INOUT:
            ee.events = EPOLLIN | EPOLLOUT;
            DEBUG("---->>>>EPOLLINOUT%p\n", sockp);
            break;
    }
    /*
    if ( sockp ) {
        epoll_ctl(epoll_fd, EPOLL_CTL_MOD, s, &ee);
    }
    else {
        epoll_ctl(epoll_fd, EPOLL_CTL_ADD, s, &ee);
        curl_multi_assign(multi_handle, s, (void *)"hahaha");
    }
*/
    return 0;
}

FILE *filep = NULL;
static size_t easy_write_cb(void *ptr, size_t size, size_t nmemb, void *data) {
    if ( filep == NULL ) {
        filep = fopen("/tmp/a.html", "w");
        assert(filep);
    }
    fwrite(ptr, size, nmemb, filep);

    size_t realsize = size * nmemb;
    DEBUG("======> size:%u\n",realsize);
    return realsize;
}

int main(int argc, char **argv) {
    if ( argc != 1 ) {
        ERROR_EXIT("get");
    }

    curl_global_init(CURL_GLOBAL_ALL);

    multi_handle = curl_multi_init();
    if ( NULL == multi_handle ) {
        ERROR_EXIT("curl_multi_init");
    }

    curl_multi_setopt(multi_handle, CURLMOPT_SOCKETFUNCTION, multi_socket_cb);
    curl_multi_setopt(multi_handle, CURLMOPT_SOCKETDATA, NULL);
    // curl_multi_setopt(multi_handle, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
    // curl_multi_setopt(multi_handle, CURLMOPT_TIMERDATA, NULL);

    epoll_fd = epoll_create(1024);
    if ( -1 == epoll_fd ) {
        ERROR_EXIT("epoll_create");
    }

    struct epoll_event ees[10];
    ees[0].data.fd = 0;
    ees[0].events = EPOLLIN;

    if ( 0 != epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 0, ees) ) {
        ERROR_EXIT("epoll_ctl");
    }

    int ret = 0;
    FILE *pFlieInput = fdopen(0, "r");

    char line[1024];
    while ( 1 ) {
        ret = epoll_wait(epoll_fd, ees, 10, 10);
        for ( int i = 0;i < ret;i++ ) {
            int fd = ees[i].data.fd;
            if ( ees[i].data.fd == 0 ) {
                fgets(line, sizeof(line), pFlieInput);
                int line_len = strlen(line);
                if ( line[line_len - 1] == '\n' ) {
                    line[line_len - 1] = 0;
                }
                DEBUG("url:%s\n", line);

                CURL *easy_handle = curl_easy_init();
                curl_easy_setopt(easy_handle, CURLOPT_URL, line);
                // curl_easy_setopt(easy_handle, CURLOPT_VERBOSE, 1L);
                curl_multi_add_handle(multi_handle, easy_handle);
                curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, easy_write_cb);
                struct timeval tv1, tv2;
                gettimeofday(&tv1, NULL);
                curl_multi_socket_action(multi_handle, CURL_SOCKET_TIMEOUT,0, &still_running);
                gettimeofday(&tv2, NULL);
                DEBUG("duration: %u\n", (tv2.tv_sec - tv1.tv_sec)*1000000+(tv2.tv_usec - tv1.tv_usec));
            // curl_easy_setopt(easy_handle, CURLOPT_PRIVATE, NULL);

            }
            else {
                // curl connection;
                int action = (ees[i].events & EPOLLIN ? CURL_CSELECT_IN : 0) | (ees[i].events & EPOLLOUT ? CURL_CSELECT_OUT : 0);
                struct timeval tv1, tv2;
                gettimeofday(&tv1, NULL);
                CURLMcode rc = curl_multi_socket_action(multi_handle, fd, action, &still_running);
                //DEBUG("TIMES:%s\n", "action");
                gettimeofday(&tv2, NULL);
                DEBUG("duration222222: %u\n", (tv2.tv_sec - tv1.tv_sec)*1000000+(tv2.tv_usec - tv1.tv_usec));
                mcode_or_die("event_cb: curl_multi_socket_action", rc);
                check_multi_info();
            }
        }
    }

    curl_multi_cleanup(multi_handle);
    curl_global_cleanup();
    return 0;
}
///////////////////////////


版本:


build:

g++ -g -Wall -o get tttt.cpp -lcurl


当我运行./get
它显示以下内容:


when i run ./get
it show following :

>./get   //enter
www.microsoft.com
url:www.microsoft.com
multi_socket_cb--------------------------------------------------------------(nil)
---->>>>EPOLLIN(nil)
duration: 748


//------------>到此为止,当您输入东西时,它会继续运行.
//为什么 ?这么说吧...,我需要做些??


//-----------> stop at this,and when you input somthing, it continue to run.
//why ? it so wire..., i need to do some ??

推荐答案

我已经完成了该程序.它可以关闭.
i have finish this program. it can be closed.


这篇关于使用c-ares和libcurl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆