libevent http client

來源:互聯網
上載者:User

我自己在實現一個http client,使用libevent,遇到一些問題,串連可以建立,但發送http請求後毫無反應。實驗了windows和linux兩個版本,都是如此。可能還是我使用上的問題。

根據網上的例子修改了一下,可以在windows下面跑,沒問題了。代碼如下:

#include <stdlib.h>#include <string.h>#include "event2/event.h"#include "event2/http.h"#include "event2/buffer.h"#include "event2/http_struct.h"#include "event2/dns.h"struct download_context{    struct evhttp_uri * uri;    struct event_base * base;    struct evdns_base * dnsbase;    struct evhttp_connection * conn;    struct evhttp_request *req;    struct evbuffer *buffer;    int ok;};static void download_callback(struct evhttp_request *req, void *arg);static int download_renew_request(struct download_context *ctx);static void download_callback(struct evhttp_request *req, void *arg){    struct download_context * ctx = (struct download_context*)arg;    struct evhttp_uri * new_uri = 0;    const char * new_location = 0;    if(!req){        printf("timeout\n");        return;    }    switch(req->response_code)    {    case HTTP_OK:        event_base_loopexit(ctx->base, 0);        break;    case HTTP_MOVEPERM:    case HTTP_MOVETEMP:        new_location = evhttp_find_header(req->input_headers, "Location");        if(!new_location) return;        new_uri = evhttp_uri_parse(new_location);        if(!new_uri)return;        evhttp_uri_free(ctx->uri);        ctx->uri = new_uri;        download_renew_request(ctx);        return;    default:/* failed */        event_base_loopexit(ctx->base, 0);        return;    }    evbuffer_add_buffer(ctx->buffer, req->input_buffer);    ctx->ok = 1;}struct download_context * context_new(const char *url){    struct download_context * ctx = 0;    ctx = (struct download_context*)calloc(1, sizeof(struct download_context));    ctx->uri = evhttp_uri_parse(url);    if(!ctx->uri) return 0;    ctx->base = event_base_new();    ctx->buffer = evbuffer_new();    ctx->dnsbase = evdns_base_new(ctx->base, 1);    download_renew_request(ctx);    return ctx;}void context_free(struct download_context *ctx){    if(ctx->conn)        evhttp_connection_free(ctx->conn);    if(ctx->buffer)        evbuffer_free(ctx->buffer);    if(ctx->uri)        evhttp_uri_free(ctx->uri);    free(ctx);}static int download_renew_request(struct download_context *ctx){    int port = evhttp_uri_get_port(ctx->uri);    if(port == -1) port = 80;    if(ctx->conn) evhttp_connection_free(ctx->conn);    printf("host:%s, port:%d, path:%s\n", evhttp_uri_get_host(ctx->uri), port, evhttp_uri_get_path(ctx->uri));    ctx->conn = evhttp_connection_base_new(ctx->base, ctx->dnsbase, evhttp_uri_get_host(ctx->uri),  port );    ctx->req = evhttp_request_new(download_callback, ctx);    evhttp_make_request(ctx->conn, ctx->req, EVHTTP_REQ_GET, evhttp_uri_get_path(ctx->uri));    evhttp_add_header(ctx->req->output_headers, "Host", evhttp_uri_get_host(ctx->uri));    return 0;}struct evbuffer *download_url(const char *url){    struct download_context * ctx = context_new(url);    if(!ctx) return 0;    event_base_dispatch(ctx->base);    struct evbuffer * retval = 0;    if(ctx->ok)    {        retval = ctx->buffer;        ctx->buffer = 0;    }    context_free(ctx);    return retval;}int main(int argc, char **argv){    struct evbuffer * data = 0;    if(argc < 2){        printf("usage: %s example.com/\n", argv[0]);        return 1;    }#ifdef WIN32WORD wVersionRequested;WSADATA wsaData;wVersionRequested = MAKEWORD(2, 2);(void) WSAStartup(wVersionRequested, &wsaData);#endif    data = download_url(argv[1]);    printf("got %d bytes\n", data ? evbuffer_get_length(data) : -1);    if(data)    {        const unsigned char * joined = evbuffer_pullup(data, -1);        printf("data itself:\n====================\n");        fwrite(joined, evbuffer_get_length(data), 1, stderr);        printf("\n====================\n");        evbuffer_free(data);    }    return 0;}

需要注意的是,如果從命令列傳入網址,比如百度的,必須傳入http://www.baidu.com/,否則解析不出來path,下載會失敗。

這個例子不是我最終想要的效果,無法控制下載和資料處理過程,它是等下載完成了一次性返回資料。對於大檔案,比如幾百兆甚至上G的,這種處理策略還不夠。我寫了一個http處理的模組和一些輔助代碼,編譯通過,可以運行,但請求發出後對端始終無反應。等我查一查,網上始終找不到libevent http client的例子,有echoserver之類的,就是沒有用戶端。

研究研究吧,可能是事件的使用上有問題。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.