1. 每個bufferevent 都擁有類型為struct evbuffer的input buffer和out buffer,分別供數據讀取和數據寫入使用。
2.讀取和寫入數據是通過編寫和設置對應的回調函數進行,而調用回調函數的時機則根據水位是否滿足來的,水位又是可以設置的。默認情況下讀的低水位是0,就是說libevent從底層讀到大於0的數據到input buffer中,讀回調函數就會調用,讀回調函數讀取input buffer的數據;同樣默認的寫水位也為0,就是說一旦output buffer中沒有數據,就會調用寫回調函數寫入數據到output buffer,ouput buffer會自動由libevent傳出到對端。
3.bufferevent 除了有讀寫事件還有其他事件
BEV_EVENT_READING:讀過程中發生的事件
BEV_EVENT_WRITING :寫過程中發生的事件
BEV_EVENT_ERROR:操作過程中發生的事件
BEV_EVENT_TIMEOUT:超時事件
BEV_EVENT_EOF:到達文件末尾
BEV_EVENT_CONNECTED:連接成功事件
4.bufferevent的選項
BEV_OPT_CLOSE_ON_FREE:釋放bufferevent的時候釋放掉底層的socket和底層的bufferevent
BEV_OPT_THREADSAFE:自動上鎖,多線程安全
BEV_OPT_DEFER_CALLBACKS:延遲所有的回調函數(通常情況下,回調函數在滿足條件的情況下是立即執行,但是同時執行的回調函數太多會可能會導致棧溢出,所以可以延遲回調函數的調用,使其成為事件循環的一部分,放入隊列,等待其他的隊列之前的回調函數被調用后在調用)
BEV_OPT_UNLOCK_CALLBACKS :在執行用戶提供的回調函數時解鎖。
5.接口
//new一個基於socket的bufferevent,如果傳入的socket fd為-1,則自動創建一個面向流的socket fd
struct bufferevent *bufferevent_socket_new(
struct event_base *base,
evutil_socket_t fd,
enum bufferevent_options options);
struct event_base *base,
evutil_socket_t fd,
enum bufferevent_options options);
//如果bev指向的基於socket的bufferevent中的socket fd沒有連接,則自動連接
//沒有連接之前是不可能從底層讀寫數據的,但是可以向output buffer寫數據
int bufferevent_socket_connect(struct bufferevent *bev,
struct sockaddr *address, int addrlen);
struct sockaddr *address, int addrlen);
//監控到連接事件成功的事件后,需要主動寫入一次,不然寫回調函數不會觸發,有點奇怪,但也可以理解
//通過主機名建立連接
int bufferevent_socket_connect_hostname(struct bufferevent *bev,
struct evdns_base *dns_base, int family, const char *hostname,
int port);
int bufferevent_socket_get_dns_error(struct bufferevent *bev);
struct evdns_base *dns_base, int family, const char *hostname,
int port);
int bufferevent_socket_get_dns_error(struct bufferevent *bev);
//釋放bufferevent
void bufferevent_free(struct bufferevent *bev);
//設置或獲取回調函數
//客戶端的寫入回調需要一個激活的過程,最好放在連接事件激活時來做
typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx);
typedef void (*bufferevent_event_cb)(struct bufferevent *bev,
bufferevent_data_cb readcb, bufferevent_data_cb writecb,
bufferevent_event_cb eventcb, void *cbarg);
void bufferevent_getcb(struct bufferevent *bufev,
bufferevent_data_cb *readcb_ptr,
bufferevent_data_cb *writecb_ptr,
bufferevent_event_cb *eventcb_ptr,
void **cbarg_ptr);
typedef void (*bufferevent_event_cb)(struct bufferevent *bev,
short events, void *ctx);
//如果事件指針設置為NULL則表示不啟用該事件的處理方式
void bufferevent_setcb(struct bufferevent *bufev,bufferevent_data_cb readcb, bufferevent_data_cb writecb,
bufferevent_event_cb eventcb, void *cbarg);
void bufferevent_getcb(struct bufferevent *bufev,
bufferevent_data_cb *readcb_ptr,
bufferevent_data_cb *writecb_ptr,
bufferevent_event_cb *eventcb_ptr,
void **cbarg_ptr);
//打開或關閉事件處理過程( EV_READ, EV_WRITE, or EV_READ|EV_WRITE)
//默認情況下新建的buffervent打開了寫事件的處理過程,沒有打開讀的處理過程
void bufferevent_enable(struct bufferevent *bufev, short events);
void bufferevent_disable(struct bufferevent *bufev, short events);
short bufferevent_get_enabled(struct bufferevent *bufev);
void bufferevent_disable(struct bufferevent *bufev, short events);
short bufferevent_get_enabled(struct bufferevent *bufev);
//設置讀寫水位
//events為( EV_READ,EV_WRITE的組合)
void bufferevent_setwatermark(struct bufferevent *bufev, short events,
size_t lowmark, size_t highmark);
size_t lowmark, size_t highmark);
//獲取讀寫evbuffer
struct evbuffer *bufferevent_get_input(struct bufferevent *bufev);
struct evbuffer *bufferevent_get_output(struct bufferevent *bufev);
struct evbuffer *bufferevent_get_output(struct bufferevent *bufev);
int bufferevent_write(struct bufferevent *bufev,
const void *data, size_t size);
int bufferevent_write_buffer(struct bufferevent *bufev,
struct evbuffer *buf);
const void *data, size_t size);
int bufferevent_write_buffer(struct bufferevent *bufev,
struct evbuffer *buf);
size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size);
int bufferevent_read_buffer(struct bufferevent *bufev,
int bufferevent_read_buffer(struct bufferevent *bufev,
struct evbuffer *buf);
//設置讀寫超時時間
void bufferevent_set_timeouts(struct bufferevent *bufev,
const struct timeval *timeout_read, const struct timeval *timeout_write);
//強制寫入或讀取
int bufferevent_flush(struct bufferevent *bufev,
short iotype, enum bufferevent_flush_mode state);
short iotype, enum bufferevent_flush_mode state);
//鎖和解鎖
void bufferevent_lock(struct bufferevent *bufev);
void bufferevent_unlock(struct bufferevent *bufev);
void bufferevent_unlock(struct bufferevent *bufev);
//其他接口
int bufferevent_priority_set(struct bufferevent *bufev, int pri);
int bufferevent_get_priority(struct bufferevent *bufev);
int bufferevent_get_priority(struct bufferevent *bufev);
int bufferevent_setfd(struct bufferevent *bufev, evutil_socket_t fd);
evutil_socket_t bufferevent_getfd(struct bufferevent *bufev);
evutil_socket_t bufferevent_getfd(struct bufferevent *bufev);
struct event_base *bufferevent_get_base(struct bufferevent *bev);
struct bufferevent *bufferevent_get_underlying(struct bufferevent *bufev);
