對于一個網(wǎng)絡模塊來說,一個緩沖模塊是必不可少的,緩沖模塊主要用于緩沖網(wǎng)絡接收的模塊,和用戶發(fā)送的模塊。
libevent在常規(guī)事件回調(diào)的基礎上提供了一個緩沖的IO抽象概念,這個抽象概念被稱為bufferevent、bufferevent提供了自動填充和釋放的輸入輸出緩沖區(qū),緩沖事件的用戶不再直接處理IO,而是從輸入緩沖區(qū)讀取數(shù)據(jù),寫入到輸出緩沖區(qū)。
libevent使用evbuffer作為網(wǎng)絡緩沖模塊,緩沖區(qū)由evbuffer和evbuffer_chain組成。evbuffer_chain是存儲數(shù)據(jù)的一塊內(nèi)存,通過指針連接在一起,組成內(nèi)存池,而evbuffer則是管理這個內(nèi)存池的鏈表。
evbuffer_chain:屬于evbuffer中單個項

evbuffer:

二者的關系

服務器用到libevent中bufferevent 中相關函數(shù)流程:
struct evconnlistener *evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb, void *ptr, unsigned flags, int backlog,? ?const struct sockaddr *sa, int socklen);
申請一個evconnlistener 對象,在給定的ip地址端口上監(jiān)聽TCP連接。新的連接到來時會觸發(fā)回調(diào)函數(shù) cb;
內(nèi)部實現(xiàn)是 完成socket(),bind,listen()這些函數(shù)之后,將此fd通過event_assign函數(shù)添加到event_base中,event_assign函數(shù)前篇有所介紹,這里不再詳述。

之前說event與event_base進行關聯(lián)使用的是event_add函數(shù),這個evconnlistener_enable就是做這個這個事情,





libevent中實現(xiàn)了大量的函數(shù)指針,初始化時將evconnlistener_event_ops 地址綁定到ops,最后調(diào)用evconnlistener_enable 函數(shù)里面操作lev->ops->enable(lev);,就執(zhí)行到了event_listener_enable函數(shù)中,次函數(shù)中再進行event_add操作。
可以理解為evconnlistener_new_bind 函數(shù)封裝了socket的API操作,然后對event與event_base進行初始化關聯(lián)操作,用戶直接直接在回調(diào)中等待新的連接即可。
bufferevent:
一個bufferevent包含了一個底層傳輸?shù)膄d,一個輸入buffer一個輸出buffer,并且bufferevent幫我們完成了從socket? ? 上接收數(shù)據(jù)寫入輸入buffer,同時從輸出buffer中取出數(shù)據(jù)通過sicket發(fā)送,當輸入輸出緩沖中的數(shù)據(jù)達到一定量的時候調(diào)用我們設置的回調(diào)函數(shù)。
bufferevent結構體中主要有
1 兩個事件(讀,寫):基本的event,等待被觸發(fā)后加入到base的活動隊列,然后調(diào)用相應的回調(diào)函數(shù),
2.兩個緩沖區(qū)(input output):存儲讀取和待發(fā)送的數(shù)據(jù)
3三個回調(diào)函數(shù)(read write error):用戶自定義
4兩個超時時間:(讀、寫超時)

bufferevent的socket事件的設置:

一:struct bufferevent *bufferevent_socket_new(struct event_base *base, evutil_socket_t fd, int options);
在給定的socket 上創(chuàng)建一個新的 socket bufferevent。
對bufferevent 結構體進行初始化操作,包含以下幾項:
1 讀寫緩沖區(qū)(input,output)的初始化

2.讀寫事件初始化操作

二:void bufferevent_setcb(struct bufferevent *bufev, bufferevent_data_cb readcb, bufferevent_data_cb writecb,? ? bufferevent_event_cb eventcb, void *cbarg);
?讀寫以及錯誤的回調(diào)函數(shù)的設置

三:int bufferevent_enable(struct bufferevent *bufev, short event)
將事件添加到event_base上,
在bufferevent_socket_new中 對be_ops 進行了賦值操作,& bufferevent_ops_socket,

bufferevent_init_common中 bufev->be_ops = ops; 即?bufev->be_ops =&bufferevent_ops_socket;

bufferevent_enable中調(diào)用了be_ops

enable函數(shù)就是指be_socket_enable函數(shù),



函數(shù)調(diào)用層層下來之后還是event_add函數(shù),將event添加到event_base上,底層epoll的epoll_ctl操作,添加節(jié)點到紅黑樹上。
以上就是使用bufferevent對 socket 讀寫監(jiān)聽的流程。