1. 程式人生 > >libevent原始碼IV--bufferevent概念

libevent原始碼IV--bufferevent概念

bufferevent基礎和概念

Libevent為這種帶快取的IO模式提供了一個通用的機制。一個”bufferevent”包含一個底層傳輸(比如socket),一個讀buffer和一個寫buffer。當底層傳輸可讀寫時就呼叫回撥函式,這是普通事件的處理,而bufferevent是在讀或寫足夠的資料時才呼叫使用者指定的回撥函式。

每個bufferevent都有一個輸入快取和一個輸出快取,對應的資料結構為struct evbuffer。當你對一個bufferevent寫資料,資料寫入到輸出快取;當有資料可讀時,你是從輸入快取中提取資料。

使用基於socket的bufferevent

基於socket的bufferevent使用起來最簡單。基於socket的bufferevent使用Libevent的底層事件機制來檢測底層網路socket是否可讀寫,也使用底層網路呼叫(比如readv,writev,WSASend,或者WSARecv)來傳輸和接收資料。

使用bufferevent_socket_new()來建立。介面如下:

struct bufferevent *bufferevent_socket_new(
    struct event_base *base,
    evutil_socket_t fd,
    enum bufferevent_options options);

base是event_base,options是bufferevent標誌的位掩碼(BEV_OPT_CLOSE_ON_FREE等)。而fd則是可選的socket fd,如果你想稍後再設定fd,可以傳-1。

bufferevent可選的標誌

在建立一個bufferevent時你可以使用一個或多個標誌。可用的標誌有:

  1. BEV_OPT_CLOSE_ON_FREE
    當bufferevent被釋放時,關閉底層傳輸。這會關閉一個底層的socker,釋放一個底層的bufferevent等。
  2. BEV_OPT_THREADSAFE
    自動為bufferevent分配鎖,所以可安全用於多執行緒。
  3. BEV_OPT_DEFER_CALLBACKS
    如果設定了這個標誌,bufferevent推遲所有回撥的執行,如上所述。
  4. BEV_OPT_UNLOCK_CALLBACKS
    預設上若一個bufferevent設定成執行緒安全,則當用戶提供的回撥呼叫時會獲取該bufferevent的鎖。設定這個標誌來讓Libevent在完成你的回撥函式後釋放bufferevent的鎖。

提示: 確保你提供的socket是非阻塞模式的,Libevent提供了一個便捷的函式evutil_make_socket_nonblocking()來設定一個socket為非阻塞。

如果成功,這個函式返回一個bufferevent,如果失敗,返回NULL。

在bufferevent上啟用連線

如果bufferevent的socket還沒連線,你可以建立一個連線,介面:

int bufferevent_socket_connect(struct bufferevent *bev,
    struct sockaddr *address, int addrlen);

引數addressaddrlen跟標準的connect()一樣。如果bufferevent還沒有一個socker,呼叫這個函式會為它建立一個新的socket,並設定socket為非阻塞。

如果bufferevent已經有一個socket,呼叫bufferevent_socket_connect()告訴Libevent該socket未連線,在連線成功之前不會有讀或寫操作返回。

在連線返回前向輸出buffer新增資料則是可以的。

如果連線成功建立,這個函式返回0,如果出現錯誤,返回-1。

參考:http://popozhu.github.io/2013/06/26/libevent_r5_bufferevent%E5%9F%BA%E7%A1%80%E5%92%8C%E6%A6%82%E5%BF%B5/

https://blog.csdn.net/luotuo44/article/details/39670221