Click here to Skip to main content
15,897,518 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
C++
#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

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 ??
Posted
Updated 5-Nov-12 3:53am
v2
Comments
Sandeep Mewara 5-Nov-12 13:59pm    
Not clear on your issue. What are you trying to do/ask?

1 solution

i have finish this program. it can be closed.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900