1概念
1.1原理
- bufferevent有兩個緩衝區:也是隊列實現只能讀一次 先進先出
- 讀緩衝: 加入讀緩衝有數據,會觸發讀緩衝對應的回調函數,在回調函數中不再使用read函數 只能使用bufferevent_read函數
- 寫緩衝bufferevent_write()向寫緩衝寫數據,這個寫緩衝一旦有數據,就自動刷新–發送給對端,
- 發送成功 write_cb()回被調用 —通知寫數據完成。
2操作函數
- 頭文件:#include<event2/bufferevent.h>
2.1創建
struct bufferevent * ev;
struct bufferevent * bufferevent_socket_new(struct event_base *base, evutil_socket_t fd, int options);
2.1.1參數
No. | 參數 | 說明 |
---|---|---|
1 | base | 創建反應器返回指針 |
2 | fd | 封裝到bufferevent內的fd |
3 | options | BEV_OPT_CLOSE_ON_FREE關閉傳輸端口,關閉套接字,釋放bufferevent |
2.1.2返回值
- 成功:返回創建的bufferevent事件對象
2.2釋放
void bufferevent_free(struct bufferevent* bev);//bev:創建返回值
2.3給bufferevent事件對象設置讀寫回調回調函數
void bufferevent_setcb(struct bufferevent *bufev,//
bufferevent_data_cb readcb, //
bufferevent_data_cb writecb,//
bufferevent_event_cb eventcb, void *cbarg)//
2.3.1參數
No. | 參數 | 說明 |
---|---|---|
1 | bufev | 創建bufferevent事件返回指針 |
2 | readcb | 設置bufferevent 讀緩衝對應的回調,自己封裝,在其內部讀數據 |
3 | writecb | 設置bufferevent 寫緩衝對應的回調,基本不用傳NULL |
1 | eventcb | 可傳NULL |
1 | cbarg | 上面3個回調函數的參數 |
2.3.2回調函數
2.3.2.1read_cb
- 函數原型
typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void
*ctx){//ctx就是cbarg
----------
bufferevent_read();
}
- 讀數據:我們定義的讀緩衝的回調函數內部要調用bufferevent_read(),其作用從bufferevent輸入的緩衝區移除事件。
- 所以要看下這個函數原型:
- ev_size_t bufferevent_read(struct bufferevent *bufev, void *data, ev_size_t size);
- 所以要看下這個函數原型:
2.3.2.2write_cb
- 函數原型
typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void
*ctx);{//ctx就是cbarg
沒有什麼用
}
- 寫數據 :bufferevent_write()原型:
- int bufferevent_write(struct bufferevent *bufev, const void *data, ev_size_t size)
2.3.2.3event_cb
- 函數原型
typedefvoid(*bufferevent_event_cb(struct bufferevent *bev, short what, void *ctx){
};
- 事件回調
what就是事件類型,類型有:
#define BEV_EVENT_READING 0x01 /**< error encountered while reading */
#define BEV_EVENT_WRITING 0x02 /**< error encountered while writing */
#define BEV_EVENT_EOF 0x10 /**< eof file reached */
#define BEV_EVENT_ERROR 0x20/**< unrecoverable error encountered */
#define BEV_EVENT_TIMEOUT 0x40 /**< user-specified timeout reached */
#define BEV_EVENT_CONNECTED 0x80 /**< connect operation finished. */(請求的
2.4禁用緩衝區和獲取緩衝區的狀態
- 禁用
void bufferevent_disable(struct bufferevent *bufev,..
short event)//EV_READ | EV_ERITE
- 啓用
short bufferevent_get_enable(struct bufferevent *bufev)
2.5啓用緩衝區
- 新建的bufferevent寫緩衝區是enable的,而讀緩衝區是disable的,所以讀的時候需要啓用讀的緩衝區。
int bufferevent_enable(struct bufferevent *bufev,..
short event)//EV_READ | EV_ERITE
2.6釋放bufferevent
void bufferevent_free(struct bufferevent *bufev);// 參數:bufferevent_socket_new的返回值
2.7連接
int bufferevent_socket_connect(struct bufferevent *bev,//bufferevent事件對象 裏面封裝了fd
struct sockaddr *address, //服務器地址
int socklen);//服務器地址長度
2.8evconnlistener_new_bind()
- 函數原型:
struct evconnlistener *evconnlistener_new_bind(
struct event_base *base,//event_base
evconnlistener_cb cb, //監聽回調函數,服務端接受連接之後,用戶要做的操作,一旦被回調,說明在其內部應該與客戶端完成連接
void *ptr, //回調函數參數
unsigned flags,
int backlog,//listen()的第二個參數 -1表示最大值
const struct sockaddr *sa, //服務器自己的地址結構
int socklen);//大小
2.8.1參數cb
- 函數原型
typedef void (*evconnlistener_cb)(struct evconn listener *listener,evutil_socket_t sock, struct sockaddr *addr, int len, void *ptr);
- 回調函數調用的時間:當接收到新連接時(即當有客戶端連接時)會調用回調函數;
- 回調參數
- listener:成功創建的監聽器,即evconnlistener_new_bind返回值;
- sock: 新接收的套接字,即客戶端的套接字
- addr和len;分別是客戶端的地址結構和長度;
- ptr:外部ptr傳進來的參數。
2.8.2參數flags
- LEV_OPT_CLOSE_ON_FREE:如果設置了這個選項,釋放連接監聽器會關閉底層套接字;
- LEV_OPT_REUSEABLE: 端口複用
2.8.3返回值
成功創佳的監聽器
3bufferevent使用步驟
- 第一步:創建event_base
- 創建 bufferevent 事件
- 給bufferevent事件對象設置回調
- 緩衝區開啓
- 緩衝區關閉:
- 釋放bufferevent
4客戶端和服務器
4.1對比
- 客戶端
- 普通 :socket() connect();
- buffer:bufferevent_socket_connect
- 服務端
- socket() bind() listen() accept()
- evconnlistener_new_bind()這一個函數相當於socket() bind() listen() accept()的作用