Libevent應用(六)從bufferevent中取出evbuffer
struct evbuffer* bufferevent_get_input(struct bufferevent *bufev); //取出輸入緩衝區 struct evbuffer* bufferevent_get_output(struct bufferevent *bufev); //取出輸出緩衝區 /*對evbuffer的操作*/ //讀到的一行內容 char *evbuffer_readln(struct evbuffer*buffer, size_t *n_read_out,enum evbuffer_eol_style eol_style); enum evbuffer_eol_style { EVBUFFER_EOL_ANY, // 任意數量的\r和\n EVBUFFER_EOL_CRLF, // \r或者\r\n EVBUFFER_EOL_CRLF_STRICT, // \r\n EVBUFFER_EOL_LF, // \n EVBUFFER_EOL_NUL // \0 }; //將資料新增到evbuffer的結尾 int evbuffer_add(struct evbuffer *buf,const void *data, size_t datlen); //從evbuffer讀取資料到data int evbuffer_remove(struct evbuffer*buf, void *data, size_t datlen); //丟掉len位元組的資料 int evbuffer_drain (struct evbuffer *buf, size_t len); //返回evbuffer中儲存的位元組長度 size_t evbuffer_get_length(const structevbuffer *buf); /*在buffer中搜尋指定字串 第一個引數是搜尋在evbuffer中, 第二個引數what是要搜尋的字串。 第三個引數len為what的字串長度, 第四個引數,如果start不為空,則會從start中所指定的位置開始搜尋,為NULL則從頭開始找。 返回值:如果找到struct evbuffer_ptr的成員pos返回對應的索引,沒有找到則pos返回-1*/ struct evbuffer_ptr evbuffer_search (struct evbuffer *buffer, const char *what, size_t len, const struct evbuffer_ptr *start); //第二個函式的不同是指定了一個搜尋範圍; struct evbuffer_ptr evbuffer_search_range (struct evbuffer *buffer, const char *what, size_t len, const struct evbuffer_ptr *start, const struct evbuffer_ptr *end); struct evbuffer_ptr { ev_ssize_t pos; //位置 struct {/* internal fields */} _internal; };
伺服器綜合程式碼:
/*************************************************************************
# File Name: tcp_server.c
# Author: wenong
# mail: huangwenlong@520it.com
# Created Time: 2016年09月03日 星期六 21時51分08秒
************************************************************************/
static struct event_base * base;
void write_buf_cb(struct bufferevent* bev, void* cbarg)
{
printf("%s\n", __FUNCTION__);
}
void read_buf_cb(struct bufferevent* bev, void* cbarg)
{
int ret, i;
char buf[MAXBYTES];
struct evbuffer* input_evbuffer = bufferevent_get_input(bev);
struct evbuffer_ptr begin, end;
while(1)
{
/*讀取a開頭,b結尾的資料包*/
begin = evbuffer_search(input_evbuffer, "a", 1, NULL);
printf("find a index %ld\n", begin.pos);
if(begin.pos >= 0)
{
evbuffer_drain(input_evbuffer, begin.pos);
end = evbuffer_search(input_evbuffer, "b", 1, NULL);
if(end.pos > 0)
{
ret = evbuffer_remove(input_evbuffer, buf, end.pos - begin.pos + 1);
buf[ret] = '\0';
printf("read_buf_cd length %d\n", ret);
for(i = 0; i < ret; i++)
buf[i] = toupper(buf[i]);
bufferevent_write(bev, buf, ret);
}
else
break;
}
else
{
bufferevent_flush(bev, EV_READ, BEV_NORMAL);
break;
}
}
}
void event_cb(struct bufferevent* bev, short event, void* cbarg)
{
if(BEV_EVENT_READING & event)
puts("BEV_EVENT_READING");
if(BEV_EVENT_WRITING & event)
puts("BEV_EVENT_WRITING");
if(BEV_EVENT_ERROR & event)
puts("BEV_EVENT_ERROR");
if(BEV_EVENT_EOF & event)
{
puts("BEV_EVENT_EOF");
bufferevent_free(bev);
}
if(BEV_EVENT_TIMEOUT & event)
{
puts("BEV_EVENT_TIMEOUT");
bufferevent_free(bev);
}
}
void accept_cb(struct evconnlistener *listener,
evutil_socket_t clientfd, struct sockaddr *addr
, int len, void *arg)
{
struct bufferevent* bev;
struct event_base* base = (struct event_base*)arg;
puts("Accept client connect");
evutil_make_socket_nonblocking(clientfd);
bev = bufferevent_socket_new(base, clientfd, BEV_OPT_CLOSE_ON_FREE
| BEV_OPT_DEFER_CALLBACKS);
bufferevent_setcb(bev, (bufferevent_data_cb)read_buf_cb
, (bufferevent_data_cb)write_buf_cb, (bufferevent_event_cb)event_cb, NULL);
struct timeval timeout_read;
timeout_read.tv_sec = 60;
timeout_read.tv_usec = 0;
bufferevent_set_timeouts(bev, &timeout_read, NULL);
bufferevent_setwatermark(bev, EV_READ, 10, 0);
bufferevent_enable(bev, EV_READ);
}
void main_loop(struct sockaddr_in * addr)
{
struct evconnlistener *evcon;
base = event_base_new();
evcon = evconnlistener_new_bind(base, (evconnlistener_cb)accept_cb
, (void*)base, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE
, 128, (struct sockaddr*)addr, sizeof(struct sockaddr_in));
puts("server begin listenning...");
event_base_dispatch(base);
evconnlistener_free(evcon);
event_base_free(base);
}
int main(int argc, char** argv)
{
int serverfd;
socklen_t serveraddrlen;
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERVERPORT);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverfd = socket(AF_INET, SOCK_STREAM, 0);
serveraddrlen = sizeof(serveraddr);
main_loop( &serveraddr);
return 0;
}
相關文章
- libevent之evbuffer
- Libevent 官方文件學習筆記(2. bufferevent部分)筆記
- 【Linux系統程式設計】libevent庫bufferevent與evconnlistenerLinux程式設計
- Libevent應用 (零) Libevent簡單介紹與安裝
- Libevent應用 (一) 建立event_base
- Libevent應用 (三) 資料緩衝
- libevent設定超時後取消超時(bufferevent_set_timeouts取消超時無效問題)
- 用sed從mysqldump全備檔案中取出某張表的表結構MySql
- Libevent應用 (二) 與事件一起工作事件
- Libevent應用 (四) 輔助型別和函式型別函式
- 使用 libevent 和 libev 提高網路應用效能
- javascript 從一組陣列中隨機取出一項JavaScript陣列隨機
- 設計模式在vue中的應用(六)設計模式Vue
- js實現從陣列中取出一個隨機項JS陣列隨機
- 在 .NET Core 中應用六邊形架構架構
- 六西格瑪在IT職場中的應用體現
- Libevent應用 (五) 連線監聽器,接收tcp連線TCP
- 從 Spark 的 DataFrame 中取出具體某一行詳解Spark
- hibernate從資料庫中取出的漢字是亂碼?資料庫
- 甘特圖在六西格瑪專案中的應用
- mysql從一張表中取出資料插入到另一張表MySql
- 用三種方式取出給定字串中的目標字串字串
- 六西格瑪在日常生活中的應用體現
- C#怎麼從List集合中隨機取出其中一個值C#隨機
- 一句話從 MySQL 取出重複行MySql
- 玩轉 PHP 網路程式設計全套之 libevent 框架多人聊天應用PHP程式設計框架
- libevent使用<一> libevent匯入專案
- 六西格瑪在改善企業流程中的應用體現
- 六西格瑪管理在北京IT專案中的應用探討
- 六西格瑪管理在團隊建設中的應用薦
- 開發者如何從應用中賺取最多的錢?
- 如何從陣列中隨機取出幾個值組成新的陣列?陣列隨機
- 為什莫從資料庫中取出的圖片不能顯示出來資料庫
- Libevent APIAPI
- [iOS 取出字串中的數字]iOS字串
- 【中後臺應用】從表單抽象到表單中臺抽象
- Linux中Libevent程式設計介紹Linux程式設計
- 部署雲應用前注意六點