1. 程式人生 > >基於libevent的http協議 學習筆記之認識基本函式(1)

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

用途:

繫結http server到一個指定的ip地址和埠,可重複呼叫該函式來繫結到同一個地址的不同埠,

引數:(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;
}