基於libevent的http協議 學習筆記之認識基本函式(1)
1. evhttp_new
宣告: struct evhttp *evhttp_new(struct event_base *base);
用途:用於建立一個新的HTTP server,
引數: base(可選)用來接收http事件, (注:可選是什麼意思暫時不清楚,歡迎補充!),
結果指標釋放:在需要釋放http server指標時,可參見函式evhttp_free()。
2. evhttp_bind_socket
宣告:int evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port);
用途:
引數:(1)http為待繫結的http server指標,(2)address為待繫結的ip地址,(3)port為待繫結的埠號,
結果:0表示繫結成功,-1表示繫結失敗。
注:跟此函式類似的一個函式為evhttp_bind_socket_with_handle,其宣告是struct evhttp_bound_socket *evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint16_t port); 與evhttp_bind_socket唯一不同的地方是返回值不同,它返回了一個socket控制代碼。
3. evhttp_accept_socket
宣告:int evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd);
用途:使http server可以接受來自指定的socket的連線,可重複呼叫來繫結到不同的socket,
引數:(1)http為待繫結的http server指標,(2)fd為待繫結的socket(該socket應已準備好接受連線),
結果:0表示成功,-1表示失敗。
注:跟此函式類似的一個函式為evhttp_accept_socket_with_handle,其宣告是struct evhttp_bound_socket *evhttp_accept_socket_with_handle(struct evhttp *http, evutil_socket_t fd); 與evhttp_accept_socket唯一不同的地方是返回值不同,它返回了一個socket控制代碼。
4. evhttp_uri_parse
宣告:struct evhttp_uri *evhttp_uri_parse(const char *source_uri);
用途:一般必定呼叫evhttp_uri_parse_with_flags,從而解析uri中的host(即ip地址或者域名)和port,
引數:source_uri為指向uri的字元指標。
注:uri指統一資源識別符號,是一個抽象概念,而url是一個具體的概念,可以根據url找到網上資源。具體可參考:https://www.zhihu.com/question/21950864
結果指標釋放:evhttp_uri_free
5. evhttp_connection_base_new
宣告:struct evhttp_connection *evhttp_connection_base_new(
struct event_base *base, struct evdns_base *dnsbase,
const char *address, unsigned short port);
用途:用於建立http請求的連線物件,即當連線物件con_obj得到了一個http request時,會主動解析address,並與之建立連線。
引數:(1)base,用於處理連線事件,(2)dnsbase,用於解析host names,一般為NULL值,(3)address,需要建立連線的對端ip地址,(4)port,需要建立連線的對端埠號
結果指標釋放:evhttp_connection_free
6. evhttp_set_timeout
宣告:void evhttp_set_timeout(struct evhttp *http, int timeout_in_secs);
用途:為一個http請求設定超時時間,
引數:(1)http,http server指標,(2)timeout_in_secs,以秒為單位
7. evhttp_request_new
宣告:struct evhttp_request *evhttp_request_new(void (*cb)(struct evhttp_request *, void *), void *arg);
用途:用於建立一個http請求,該請求的內容未初始化,建立完後需立即填充(參考evhttp_add_header),
引數:(1)cb,為回撥函式,當http 請求完成後(傳送到對端成功,或者出現錯誤)被呼叫,(2)arg為任意需要在cb中使用的引數。
結果指標釋放:evhttp_request_free
8. evhttp_add_header
宣告:int evhttp_add_header(struct evkeyvalq *headers, const char *key, const char *);
用途:為已存在的http請求頭部新增另外的頭部,
引數:(1)headers,為http請求的output_headers,(2)key,為headers的名字,(3)value,為headers的值。
結果:0表示成功,-1表示失敗
9. evhttp_make_request
宣告:int evhttp_make_request(struct evhttp_connection *evcon, struct evhttp_request *req, enum evhttp_cmd_type type, const char *uri);
用途:為指定的一個連線建立一個http請求,這個連線屬於該http請求物件req,連線失敗時,req不再有效,該指標已經被釋放了,
引數:(1)evcon, http連線,(2)req,已經建立好並已配置好的http請求,(3)type,該http請求的型別,EVHTTP_REQ_GET、EVHTTP_REQ_POST等
(4)uri,與該http請求相對應
結果:0表示成功,-1表示失敗
注:需要取消http請求,可參考evhttp_cancel_request
另附基於libevent的http client簡單版本:
#include <event2/event_struct.h>
#include <event2/event.h>
#include <event2/bufferevent.h>
#include <event2/http.h>
#include "evhttp.h"
int init_win_socket()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
return -1;
}
return 0;
}
//http請求回撥函式,用於處理伺服器端的返回訊息
void http_request_done(struct evhttp_request *req, void *arg)
{
printf("send request ok...\n");
size_t len = evbuffer_get_length(req->input_buffer);
unsigned char * str = evbuffer_pullup(req->input_buffer, len);
char buf[256] = { 0 };
memcpy(buf, str, len);
if (str == NULL)
{
printf("len = %d, str == NULL\n", len);
}
else
{
printf("len = %d, str = %s\n", len, buf);
}
event_base_loopbreak((struct event_base*)arg);
}
int main()
{
struct event_base* base;
struct evhttp_connection* conn;
struct evhttp_request* req;
#ifdef WIN32
init_win_socket();
#endif
base = event_base_new();
//conn = evhttp_connection_new(base, NULL, "192.168.1.109", 8081);
conn = evhttp_connection_new("127.0.0.1", 8081); //建立與服務端的連結
evhttp_connection_set_base(conn, base); //連結託管到新建的base上
req = evhttp_request_new(http_request_done, base); //建立http請求物件
evhttp_add_header(req->output_headers, "Host", "localhost"); //填充http請求頭內容
evhttp_make_request(conn, req, EVHTTP_REQ_GET, "/test"); //傳送http請求
evhttp_connection_set_timeout(req->evcon, 600); //設定超時時間,超過這個時間還沒收到服務端訊息,則自動回撥本地回撥函式http_request_done
event_base_dispatch(base); //死迴圈,等待服務端響應
evhttp_connection_free(conn);
event_base_free(base);
printf("run over...\n");
system("pause");
return 0;
}