libcurl总是超时错误C ++

时间:2017-03-30 21:16:44

标签: c++ libcurl

我目前正在使用libcurl库的多接口API来发送多个HTTP请求而不会阻塞。我目前的问题是我无法发送HTTP请求。

由于某种原因,maxfd始终为-1,导致rc始终为0.因此,当代码到达switch语句时,它始终打印" timeout"因为rc总是0。

之前我从未使用过mulit界面,但我使用了简单的界面几次。大部分代码与this非常相似。

ReqestHandler.cpp

void RequestHandler::add(lua_State* lua, const std::string& url, const std::string& data) { 
Request request;

CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "RoBot/ Version 1");
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 0);

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &request.response);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &request.headers);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &request.code);

if (!data.empty()) {
    curl_easy_setopt(curl, CURLOPT_POST, true);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.size());
}

request.curl = curl;
request.lua = lua;

curl_multi_add_handle(_curlm, curl);
_requests.push_back(request);
}


void RequestHandler::tick() {
if (!_requests.empty()) {
    curl_multi_perform(_curlm, &_isRunning);

    do {
        struct timeval timeout;
        int rc;
        CURLMcode mc;

        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);

        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
        curl_multi_timeout(_curlm, &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;
            }
        }

        mc = curl_multi_fdset(_curlm, &fdread, &fdwrite, &fdexcep, &maxfd);

        if (mc != CURLM_OK) {
            throw new Exception("MC error code: " + mc);
            break;
        }

        if (maxfd == -1) {
            Sleep(1000);
            rc = 0;
        } else {
            rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
        }

        switch (rc) {
        case -1:
            /* select error */
            std::cout << "Error" << std::endl;
            break;
        case 0:
            /* timeout */
            std::cout << "Timeout" << std::endl;
            break;
        default:
            /* action */
            std::cout << "Action" << std::endl;
            curl_multi_perform(_curlm, &_isRunning);
            break;
        }
    } while (_isRunning);

    while ((_msg = curl_multi_info_read(_curlm, &_msgsLeft))) { 
        std::cout << "RAN";
        if (_msg->msg == CURLMSG_DONE) {
            for (unsigned int i = 0; i < _requests.size(); i++) {
                Request request = _requests[i];

                if (_msg->easy_handle == request.curl) {
                    std::cout << request.response << std::endl;
                    break;
                }
            }
        }
    }

    curl_multi_cleanup(_curlm);

    for (unsigned int i = 0; i < _requests.size(); i++) {
        curl_easy_cleanup(_requests[i].curl);
        _requests.erase(_requests.begin() + i);
    }
}
}

RequestHandler.h

#pragma once
#include <string>
#include <vector>
#include "curl\curl.h"
#include "Lua\lua.hpp"

struct Request {
std::string response;
std::string headers;

int code;

CURL* curl;
lua_State* lua;
};

class RequestHandler {
public:
RequestHandler();
~RequestHandler();

static RequestHandler* getInstance();

void add(lua_State* lua, const std::string& url, const std::string& data);

void tick();

private:
static RequestHandler* INSTANCE;
std::vector<Request> _requests;
CURLM* _curlm;
CURLMsg* _msg;
int _isRunning;
int _msgsLeft; 
};

更新

根据评论中的建议,我使用了CURLOPT_STDERR和CURLOPT_VERBOSE,并且没有任何内容打印到输出文件。

我在RequestHandler:add();函数中添加了此代码。

#ifdef _DEBUG
    FILE* file = fopen("../Logs/Verbose.log", "wb");
    curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
    curl_easy_setopt(curl, CURLOPT_STDERR, file);
#endif

文件确实已创建,但没有任何内容写入文件。

0 个答案:

没有答案