libevent為我們供給了一個很便利的組件bufferevent,可以將底層的通信接口抽象為緩存操縱,可以使我們無須本身再直接處理懲罰 套接口的發送和接管,並在其上供給讀、寫、事務回調,具體的文檔可參考([翻譯]libevent參考手冊第六章:bufferevent:概念和入門) 是一份官方文檔的翻譯,然則該文章中沒有說清楚bufferevent的觸發前提,僅說了凹凸水位觸發等景象,我想知道的是bufferevent是程度 觸發還是邊沿出發的,比如說讀事務已觸發然則我發明緩沖中沒有足夠的數據,不讀空緩沖中的數據,則下次再次觸發讀事務是在什么時辰?是類似程度觸發,只要 讀緩沖區中稀有據就不絕的觸發還是鄙人次稀有據參加讀緩沖區時觸發?
故只有寫代碼本身去驗證。客戶端采取bufferevent連接辦事端,注冊讀和錯誤事務回調,辦事端從終端上每次讀取一行數據發往客戶端,客戶端觸發讀事務回調后並不讀空讀緩存,以此查看bufferevent的回調是程度觸發還是邊沿觸發的。
客戶端代碼client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <event2/event.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#define SVRADDR "127.0.0.1"
#define PORT 7890
staticvoid buff_input_cb(struct bufferevent *bev, void*ctx) {
printf("***in %s\n", __func__);
printf("len=%d\n", evbuffer_get_length(bufferevent_get_input(bev)));
return;
}
staticvoid buff_ev_cb(struct bufferevent *bev, short events, void*ctx) {
printf("in %s\n", __func__);
if (events & BEV_EVENT_CONNECTED) {
printf("***BEV_EVENT_CONNECTED\n");
} elseif (events & BEV_EVENT_ERROR) {
printf("***BEV_EVENT_ERROR\n");
}
return;
}
int main() {
int sockfd;
struct event_base *p_base;
struct bufferevent *p_event;
struct sockaddr_in addr;;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, SVRADDR, &addr.sin_addr) <=0) {
printf("inet_pton");
exit(1);
}
if ((p_base = event_base_new()) == NULL) {
printf("event_base_new ");
return1;
}
if ((p_event = bufferevent_socket_new(p_base, -1, BEV_OPT_CLOSE_ON_FREE)) == NULL) {
printf("bufferevent_socket_new ");
return1;
}
if ((sockfd = bufferevent_socket_connect(p_event, (struct sockaddr *)&addr, sizeof(addr))) <0) {
printf("bufferevent_socket_connect ");
return1;
}
bufferevent_setcb(p_event, buff_input_cb, NULL, buff_ev_cb, p_base);
bufferevent_enable(p_event, EV_READ);
event_base_dispatch(p_base);
return0;
}