libevent網絡庫--bufferevent

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使用步驟

  1. 第一步:創建event_base
  2. 創建 bufferevent 事件
  3. 給bufferevent事件對象設置回調
  4. 緩衝區開啓
  5. 緩衝區關閉:
  6. 釋放bufferevent

4客戶端和服務器

4.1對比

  • 客戶端
    • 普通 :socket() connect();
    • buffer:bufferevent_socket_connect
  • 服務端
    • socket() bind() listen() accept()
    • evconnlistener_new_bind()這一個函數相當於socket() bind() listen() accept()的作用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章