我目前正在使用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
文件确实已创建,但没有任何内容写入文件。