我正在寻找一个能在Windows和Linux上使用的C/C++库,可以让我异步查询多个Web服务器(每分钟数千个),并以与WinHttp库在Windows环境中类似的方式下载网页标题和网页。
到目前为止,我发现libCurl似乎可以满足我的要求,但是异步方面看起来有些可疑。
您认为绕过使用库并从头开始编写基于套接字的简单程序以实现此目的有多容易?
欢迎任何评论、建议或建议。
补充说明:- 有关使用libCurl执行此操作的任何评论,我说异步方面可能会有问题,但是否有任何经验呢?
我正在寻找一个能在Windows和Linux上使用的C/C++库,可以让我异步查询多个Web服务器(每分钟数千个),并以与WinHttp库在Windows环境中类似的方式下载网页标题和网页。
到目前为止,我发现libCurl似乎可以满足我的要求,但是异步方面看起来有些可疑。
您认为绕过使用库并从头开始编写基于套接字的简单程序以实现此目的有多容易?
欢迎任何评论、建议或建议。
补充说明:- 有关使用libCurl执行此操作的任何评论,我说异步方面可能会有问题,但是否有任何经验呢?
尝试使用libevent的HTTP例程。你可以创建一个HTTP连接并提供一个回调函数,在收到响应(或超时事件触发)时调用它。
更新: 我构建了一个分布式HTTP连接限流代理,并在同一个守护程序中使用了客户端和服务器部分,全部在单个线程上运行,效果很好。
如果你正在编写一个HTTP客户端,libevent 应该是很合适的选择。在服务端方面,唯一的限制是缺少配置选项--如果你想添加更高级功能,API 有点不够充足;不过这也是我预期的,因为它从来没有打算替换像Apache、Nginx这样的通用Web服务器。例如,我对其进行了补丁,以添加自定义子例程,限制入站HTTP请求的总大小(例如,在读取10MB后关闭连接)。代码非常精简易懂,补丁很容易实现。
我使用的是1.3.x分支;2.x分支相较于旧版有一些严重的性能改进。
代码示例:花了几分钟写了一个快速示例,这应该能让你熟悉libevent的编程风格:
#include <stdio.h>
#include <event.h>
#include <evhttp.h>
void
_reqhandler(struct evhttp_request *req, void *state)
{
printf("in _reqhandler. state == %s\n", (char *) state);
if (req == NULL) {
printf("timed out!\n");
} else if (req->response_code == 0) {
printf("connection refused!\n");
} else if (req->response_code != 200) {
printf("error: %u %s\n", req->response_code, req->response_code_line);
} else {
printf("success: %u %s\n", req->response_code, req->response_code_line);
}
event_loopexit(NULL);
}
int
main(int argc, char *argv[])
{
const char *state = "misc. state you can pass as argument to your handler";
const char *addr = "127.0.0.1";
unsigned int port = 80;
struct evhttp_connection *conn;
struct evhttp_request *req;
printf("initializing libevent subsystem..\n");
event_init();
conn = evhttp_connection_new(addr, port);
evhttp_connection_set_timeout(conn, 5);
req = evhttp_request_new(_reqhandler, (void *)state);
evhttp_add_header(req->output_headers, "Host", addr);
evhttp_add_header(req->output_headers, "Content-Length", "0");
evhttp_make_request(conn, req, EVHTTP_REQ_GET, "/");
printf("starting event loop..\n");
event_dispatch();
return 0;
}
编译并运行:
% gcc -o foo foo.c -levent
% ./foo
initializing libevent subsystem..
starting event loop..
in _reqhandler. state == misc. state you can pass as argument to your handler
success: 200 OK
微软的cpprestsdk是一个跨平台的http库,可以与http服务器进行通信。在这里有一些msdn上的示例代码。它在Linux上使用boost asio,在Windows上使用WinHttp。
尝试 https://github.com/ithewei/libhv
libhv是一个跨平台的轻量级网络库,用于开发TCP/UDP/SSL/HTTP/WebSocket客户端/服务器。
HTTP客户端示例:
auto resp = requests::get("http://127.0.0.1:8080/ping");
if (resp == NULL) {
printf("request failed!\n");
} else {
printf("%d %s\r\n", resp->status_code, resp->status_message());
printf("%s\n", resp->body.c_str());
}
hv::Json jroot;
jroot["user"] = "admin";
jroot["pswd"] = "123456";
http_headers headers;
headers["Content-Type"] = "application/json";
resp = requests::post("127.0.0.1:8080/echo", jroot.dump(), headers);
if (resp == NULL) {
printf("request failed!\n");
} else {
printf("%d %s\r\n", resp->status_code, resp->status_message());
printf("%s\n", resp->body.c_str());
}
// async
int finished = 0;
Request req(new HttpRequest);
req->url = "http://127.0.0.1:8080/echo";
req->method = HTTP_POST;
req->body = "This is an async request.";
req->timeout = 10;
requests::async(req, [&finished](const HttpResponsePtr& resp) {
if (resp == NULL) {
printf("request failed!\n");
} else {
printf("%d %s\r\n", resp->status_code, resp->status_message());
printf("%s\n", resp->body.c_str());
}
finished = 1;
});
更多用法请参见https://github.com/ithewei/libhv/blob/master/examples/http_client_test.cpp