2014-04-01 49 views
1

我嘗試運行卷曲多接口示例:http://curl.haxx.se/libcurl/c/multi-single.html捲曲多接口不工作

我正在使用mingw g ++。

首先我得到一個錯誤「undefined reference to'select @ 20'」。

我在編譯器中添加了「-lws2_32」。

現在沒有編譯錯誤,但程序打印出「select()返回錯誤,這是不好的」。

我在做什麼錯?

#include <stdio.h> 
#include <string.h> 

/* somewhat unix-specific */ 
#include <sys/time.h> 
#include <unistd.h> 

/* curl stuff */ 
#include <curl/curl.h> 

/* 
* Simply download a HTTP file. 
*/ 
int main(void) 
{ 
    CURL *http_handle; 
    CURLM *multi_handle; 

    int still_running; /* keep number of running handles */ 

    curl_global_init(CURL_GLOBAL_DEFAULT); 

    http_handle = curl_easy_init(); 

    /* set the options (I left out a few, you'll get the point anyway) */ 
    curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/"); 

    /* init a multi stack */ 
    multi_handle = curl_multi_init(); 

    /* add the individual transfers */ 
    curl_multi_add_handle(multi_handle, http_handle); 

    /* we start some action by calling perform right away */ 
    curl_multi_perform(multi_handle, &still_running); 

    do { 
    struct timeval timeout; 
    int rc; /* select() return code */ 

    fd_set fdread; 
    fd_set fdwrite; 
    fd_set fdexcep; 
    int maxfd = -1; 

    long curl_timeo = -1; 

    FD_ZERO(&fdread); 
    FD_ZERO(&fdwrite); 
    FD_ZERO(&fdexcep); 

    /* set a suitable timeout to play around with */ 
    timeout.tv_sec = 1; 
    timeout.tv_usec = 0; 

    curl_multi_timeout(multi_handle, &curl_timeo); 
    if(curl_timeo >= 0) { 
     timeout.tv_sec = curl_timeo/1000; 
     if(timeout.tv_sec > 1) 
     timeout.tv_sec = 1; 
     else 
     timeout.tv_usec = (curl_timeo % 1000) * 1000; 
    } 

    /* get file descriptors from the transfers */ 
    curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); 

    /* In a real-world program you OF COURSE check the return code of the 
     function calls. On success, the value of maxfd is guaranteed to be 
     greater or equal than -1. We call select(maxfd + 1, ...), specially in 
     case of (maxfd == -1), we call select(0, ...), which is basically equal 
     to sleep. */ 

    rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); 

    switch(rc) { 
    case -1: 
     /* select error */ 
     still_running = 0; 
     printf("select() returns error, this is badness\n"); 
     break; 
    case 0: 
    default: 
     /* timeout or readable/writable sockets */ 
     curl_multi_perform(multi_handle, &still_running); 
     break; 
    } 
    } while(still_running); 

    curl_multi_remove_handle(multi_handle, http_handle); 

    curl_easy_cleanup(http_handle); 

    curl_multi_cleanup(multi_handle); 

    curl_global_cleanup(); 

    return 0; 
} 

回答

0

您的maxfd返回-1。

http://curl.haxx.se/libcurl/c/curl_multi_fdset.html提取物:

如果沒有文件描述符是由libcurl的設置,max_fd將包含-1時 這個函數返回。否則它將包含更高描述符 數字libcurl集合。當libcurl在max_fd中返回-1時,這是因爲 libcurl當前做了某些事情, 應用程序無法通過套接字進行監視,然而不幸的是,您可能不知道使用select()完成當前操作的確切時間。 當max_fd返回-1時,您需要等待一段時間,然後繼續執行 並調用curl_multi_perform。要等多久?我建議 至少100毫秒,但你可能想要在你自己的 特定條件下進行測試以找到合適的值。

所以,儘量用延遲:

#if defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS__) || defined(__TOS_WIN__) 

    #include <windows.h> 

    inline void delay(unsigned long ms) 
    { 
    Sleep(ms); 
    } 

#else /* presume POSIX */ 

    #include <unistd.h> 

    inline void delay(unsigned long ms) 
    { 
    usleep(ms * 1000); 
    } 

#endif 

#include <stdio.h> 
#include <string.h> 

/* somewhat unix-specific */ 
#include <sys/time.h> 
#include <unistd.h> 

/* curl stuff */ 
#include <curl/curl.h> 

/* 
* Simply download a HTTP file. 
*/ 
int main(void) 
{ 
    CURL *http_handle; 
    CURLM *multi_handle; 

    int still_running; /* keep number of running handles */ 

    curl_global_init(CURL_GLOBAL_DEFAULT); 

    http_handle = curl_easy_init(); 

    /* set the options (I left out a few, you'll get the point anyway) */ 
    curl_easy_setopt(http_handle, CURLOPT_URL, "http://www.example.com/"); 

    /* init a multi stack */ 
    multi_handle = curl_multi_init(); 

    /* add the individual transfers */ 
    curl_multi_add_handle(multi_handle, http_handle); 

    /* we start some action by calling perform right away */ 
    curl_multi_perform(multi_handle, &still_running); 

    do { 
    struct timeval timeout; 
    int rc; /* select() return code */ 

    fd_set fdread; 
    fd_set fdwrite; 
    fd_set fdexcep; 
    int maxfd = -1; 

    long curl_timeo = -1; 

    FD_ZERO(&fdread); 
    FD_ZERO(&fdwrite); 
    FD_ZERO(&fdexcep); 

    /* set a suitable timeout to play around with */ 
    timeout.tv_sec = 1; 
    timeout.tv_usec = 0; 

    curl_multi_timeout(multi_handle, &curl_timeo); 
    if(curl_timeo >= 0) { 
     timeout.tv_sec = curl_timeo/1000; 
     if(timeout.tv_sec > 1) 
     timeout.tv_sec = 1; 
     else 
     timeout.tv_usec = (curl_timeo % 1000) * 1000; 
    } 

    /* get file descriptors from the transfers */ 
    curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); 

    /* In a real-world program you OF COURSE check the return code of the 
     function calls. On success, the value of maxfd is guaranteed to be 
     greater or equal than -1. We call select(maxfd + 1, ...), specially in 
     case of (maxfd == -1), we call select(0, ...), which is basically equal 
     to sleep. */ 

    while(rc==-1){ 
     delay(1); 
     rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); 
    } 

    switch(rc) { 
    case -1: 
     /* select error */ 
     still_running = 0; 
     printf("select() returns error, this is badness\n"); 
     break; 
    case 0: 
    default: 
     /* timeout or readable/writable sockets */ 
     curl_multi_perform(multi_handle, &still_running); 
     break; 
    } 
    } while(still_running); 

    curl_multi_remove_handle(multi_handle, http_handle); 

    curl_easy_cleanup(http_handle); 

    curl_multi_cleanup(multi_handle); 

    curl_global_cleanup(); 

    return 0; 
} 

我希望這將有助於。