Libevent API

劉秋杉發表於2015-03-13

evtimer_new

evtimer_new(base, callback, NULL)

用來做定時器,即當達到一定時間後呼叫回撥函式callback,用evtimer_add啟用定時器。例如:

my_node->ev_expect_ping = 
evtimer_new(my_node->base,expected_leader_ping_period
,(void*)my_node);  
evtimer_del(my_node->ev_expect_ping);  
evtimer_add(my_node->ev_expect_ping,
&my_node->config.expect_ping_timeval);  

我們在my->base上建立了一個定時器my_node->ev_expect_ping,並繫結這個定時器上的定時事件expected_leader_ping_period,然後先用evtimer_del禁用這個定時器,再用evtimer_add啟用定時器,設定expect_ping_timeval後觸發。


bufferevent

struct bufferevent {  
               struct event_base *ev_base;  
        const struct bufferevent_ops *be_ops;  
        struct event ev_read;  
        struct event ev_write;  
        struct evbuffer *input;  
        struct evbuffer *output;  
        ……  
        bufferevent_data_cb readcb;  
        bufferevent_data_cb writecb;  
        bufferevent_event_cb errorcb;  
        ……  
}  

bufferevent 內建了兩個event(讀/寫)和對應的緩衝區,當有資料被讀入(input)時,readcb被呼叫,當output被輸出完成的時候,writecb被呼叫。
當網路I/O出現錯誤,如連結中斷,超時或其他錯誤時,errorcb被呼叫,例如 :BEV_EVENT_ERROR
如果bufferevent出現這個事件,表示操作時發生錯誤,如果你是將bufferevent用作socket通訊,這個錯誤一般意味著socket連線斷開。更多的錯誤資訊需要呼叫EVUTIL_SOCKET_ERROR()。

bufferevent由一個底層的傳輸埠(如套接字),一個讀取緩衝區和一個寫入緩衝區組成。與通常的事件在底層傳輸埠已經就緒,可以讀取或者寫入的時候執行回撥不同的是,bufferevent在讀取或者寫入了足夠量的資料之後呼叫使用者提供的回撥。

bufferevent_write(struct bufferevent *bufev, const void *data, size_t size)

把資料寫入一個bufferevent buffer中,它被用來將資料寫入檔案描述符,當資料變得能夠寫時,會自動寫入到描述符中。

struct bufferevent * bufferevent_socket_new (struct event_base *base,evutil_socket_t fd, int options)  

bufferevent_socket_new在一個已經存在的socket(fd)上建立一個新的socket bufferevent,bufferevent是在event和evbuffer之上的一層封裝,為輸入和輸出各提供了一個event(分別是ev_read和ev_write)和相應的buffer。

void bufferevent_setcb (struct bufferevent *bufev, bufferevent_data_cb readcb, bufferevent_data_cb writecb, bufferevent_event_cb eventcb, void *cbarg)  

bufferevent_setcb()函式修改bufferevent的一個或者多個回撥。readcb、writecb和eventcb函式將分別在已經讀取足夠的資料、已經寫入足夠的資料,或者發生錯誤時被呼叫。每個回撥函式的第一個引數都是發生了事件的bufferevent,最後一個引數都是呼叫bufferevent_setcb()時使用者提供的cbarg引數:可以通過它向回撥傳遞資料。

int bufferevent_enable (struct bufferevent *bufev, short event)

當bufferevent初始化後,呼叫bufferevent_enable來啟用,引數event指定bufferevent可以進行的事件,如,如果是EV_READ,則進行讀。


evconnlistener_new_bind

用evconnlistener_new_bind即可完成一個服務端socket的建立。

struct evconnlistener *evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb, void *ptr, unsigned flags, int backlog, const struct sockaddr *sa, int socklen);  

分配和返回一個新的連線監聽器物件,base引數是監聽器用於監聽連線的event_base,即連線監聽器使用event_base來得知什麼時候在給定的監聽套接字const struct sockaddr *sa(包含ip和埠)上有新的TCP連線,新連線到達時,監聽器呼叫你給出的回撥函式cb。


evconnlistener_new

struct evconnlistener *evconnlistener_new(struct event_base *base, evconnlistener_cb cb, void *ptr, unsigned flags, int backlog, evutil_socket_t fd)

上面的兩個Evconnlistener_new*() 函式都分配並返回一個新的連線監聽器物件。連線偵聽器使用event_base獲得通知,當在一個監聽套接字上有一個新的TCP連線。當一個新的連線到達時,它將呼叫你所提供的回撥函式。
在這兩個函式中,偵聽器使用一個event_base型別的base引數去偵聽連線。當一個新連線被接受時,回撥函式Cb將被呼叫;若回撥cb是 NULL,監聽器將被視為禁用直到設定回撥。Ptr指標將傳遞給回撥。Flags引數控制偵聽器的行為。backlog引數控制著掛起連線的最大的數目,即任何時間網路堆疊應該允許等待中尚未接受的狀態的數目。如果backlog是負的,Libevent 將嘗試為backlog設定一個適當的值;如果它是零,Libevent 將假定您已經在套接字上呼叫 listen()。
這兩個函式設定監聽套接字的方式不同。Evconnlistener_new() 函式假設您已有套接字已經與埠繫結,並且以fd引數傳遞。如果您希望自己讓Libevent 分配和繫結到套接字上,呼叫 evconnlistener_new_bind(),傳遞sockaddr引數的和它的長度。
要釋放連線的偵聽器,請將它傳遞給 evconnlistener_free()。


evbuffer_remove

int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen);  

evbuffer_remove() 函式將複製和刪除前面的buf的datlen個位元組到記憶體中的data中。如果少於datlen個位元組可用,函式將複製所有的位元組。失敗返回的值是-1,否則返回複製的位元組數。
示例

struct evbuffer* evb = bufferevent_get_input(bev);  
evbuffer_remove(evb,msg_buf,SYS_MSG_HEADER_SIZE+data_size);

從一個bufferevent叫bev中讀取資料到evbuffer evb中,再轉到msg_buf中。


相關文章