日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

libevent简介和使用

發(fā)布時間:2023/12/2 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 libevent简介和使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
libevent是一個基于事件觸發(fā)的網(wǎng)絡(luò)庫,memcached底層也是使用libevent庫,今天學(xué)習(xí)下。

總體來說,libevent有下面一些特點和優(yōu)勢:
* 統(tǒng)一數(shù)據(jù)源, 統(tǒng)一I/O事件,信號和定時器這三種事件;

* 可移植,跨平臺支持多種I/O多路復(fù)用技術(shù), epoll、poll、dev/poll、select 和kqueue 等;

* 對并發(fā)編程支持,避免競態(tài)條件;

* 高性能,由事件驅(qū)動;

* 輕量級,專注于網(wǎng)絡(luò);


libevent有下面幾大部分組成:

*?事件管理包括各種IO(socket)、定時器、信號等事件,也是libevent應(yīng)用最廣的模塊;

*?緩存管理是指evbuffer功能;

*?DNS是libevent提供的一個異步DNS查詢功能;

*?HTTP是libevent的一個輕量級http實現(xiàn),包括服務(wù)器和客戶端


一些資料:
* libevent官網(wǎng):http://libevent.org/?
* libevent API:http://www.monkey.org/~provos/libevent/doxygen-2.0.1/index.html
* CSDN上剖析得很贊的文章:http://blog.csdn.net/sparkliang/article/details/4957667


// =============================================================================================


下面寫了2個簡單的使用例子,一個是定時器,一個是TCP服務(wù)器,都只涉及到libevent的事件管理模塊。


一、簡單定時器:實現(xiàn)程序每秒輸出一個“Game Over!”

event_init() =>?evtimer_set() =>?event_add() =>event_dispatch()

[cpp]?view plaincopy
  • #include?<stdio.h>??
  • #include?<iostream>??
  • ??
  • //?libevent頭文件??
  • #include?<event.h>??
  • using?namespace?std;??
  • ??
  • //?定時事件回調(diào)函數(shù)??
  • void?onTime(int?sock,?short?event,?void?*arg)??
  • {??
  • ????cout?<<?"Game?Over!"?<<?endl;??
  • ??
  • ????struct?timeval?tv;??
  • ????tv.tv_sec?=?1;??
  • ????tv.tv_usec?=?0;??
  • ????//?重新添加定時事件(定時事件觸發(fā)后默認自動刪除)??
  • ????event_add((struct?event*)arg,?&tv);??
  • }??
  • ??
  • int?main()??
  • {??
  • ????//?初始化??
  • ????event_init();??
  • ??
  • ????struct?event?evTime;??
  • ????//?設(shè)置定時事件??
  • ????evtimer_set(&evTime,?onTime,?&evTime);??
  • ??
  • ????struct?timeval?tv;??
  • ????tv.tv_sec?=?1;??
  • ????tv.tv_usec?=?0;??
  • ????//?添加定時事件??
  • ????event_add(&evTime,?&tv);??
  • ??
  • ????//?事件循環(huán)??
  • ????event_dispatch();??
  • ??
  • ????return?0;??
  • }??
  • 編譯并執(zhí)行,編譯加 -levent:

    [cpp]?view plaincopy
  • gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest?#?mv?time.cpp?timer.cpp??
  • gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest?#?g++?-o?timer?timer.cpp?-levent??
  • gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest?#?./timer???
  • Game?Over!??
  • Game?Over!??
  • Game?Over!??
  • Game?Over!??

  • 二、TCP服務(wù)器: 實現(xiàn)監(jiān)聽本機8888端口并輸出客戶端發(fā)送過來的信息

    event_base_new()=>event_set()=>event_base_set()=>event_add()=>event_base_dispatch()

    [cpp]?view plaincopy
  • #include?<stdio.h>??
  • #include?<string.h>??
  • #include?<iostream>??
  • #include?<sys/socket.h>??????
  • #include?<netinet/in.h>??????
  • #include?<arpa/inet.h>??????
  • #include?<netdb.h>??
  • ??
  • #include?<event.h>??
  • using?namespace?std;??
  • ??
  • //?事件base??
  • struct?event_base*?base;??
  • ??
  • //?讀事件回調(diào)函數(shù)??
  • void?onRead(int?iCliFd,?short?iEvent,?void?*arg)??
  • {??
  • ????int?iLen;??
  • ????char?buf[1500];??
  • ??
  • ????iLen?=?recv(iCliFd,?buf,?1500,?0);??
  • ??
  • ????if?(iLen?<=?0)?{??
  • ????????cout?<<?"Client?Close"?<<?endl;??
  • ??
  • ????????//?連接結(jié)束(=0)或連接錯誤(<0),將事件刪除并釋放內(nèi)存空間??
  • ????????struct?event?*pEvRead?=?(struct?event*)arg;??
  • ????????event_del(pEvRead);??
  • ????????delete?pEvRead;??
  • ??
  • ????????close(iCliFd);??
  • ????????return;??
  • ????}??
  • ??
  • ????buf[iLen]?=?0;??
  • ????cout?<<?"Client?Info:"?<<?buf?<<?endl;??
  • }??
  • ??
  • //?連接請求事件回調(diào)函數(shù)??
  • void?onAccept(int?iSvrFd,?short?iEvent,?void?*arg)??
  • {??
  • ????int?iCliFd;??
  • ????struct?sockaddr_in?sCliAddr;??
  • ??
  • ????socklen_t?iSinSize?=?sizeof(sCliAddr);??
  • ????iCliFd?=?accept(iSvrFd,?(struct?sockaddr*)&sCliAddr,?&iSinSize);??
  • ??
  • ????//?連接注冊為新事件?(EV_PERSIST為事件觸發(fā)后不默認刪除)??
  • ????struct?event?*pEvRead?=?new?event;??
  • ????event_set(pEvRead,?iCliFd,?EV_READ|EV_PERSIST,?onRead,?pEvRead);??
  • ????event_base_set(base,?pEvRead);??
  • ????event_add(pEvRead,?NULL);??
  • }??
  • ??
  • int?main()??
  • {??
  • ??
  • ????int?iSvrFd;????
  • ????struct?sockaddr_in?sSvrAddr;??
  • ????????????????
  • ????memset(&sSvrAddr,?0,?sizeof(sSvrAddr));????
  • ????sSvrAddr.sin_family?=?AF_INET;????
  • ????sSvrAddr.sin_addr.s_addr?=?inet_addr("127.0.0.1");??????
  • ????sSvrAddr.sin_port?=?htons(8888);?????
  • ??????????????????????????????
  • ????//?創(chuàng)建tcpSocket(iSvrFd),監(jiān)聽本機8888端口????
  • ????iSvrFd?=?socket(AF_INET,?SOCK_STREAM,?0);????
  • ????bind(iSvrFd,?(struct?sockaddr*)&sSvrAddr,?sizeof(sSvrAddr));????
  • ????listen(iSvrFd,?10);??
  • ??
  • ????//?初始化base??
  • ????base?=?event_base_new();??
  • ??????
  • ????struct?event?evListen;??
  • ????//?設(shè)置事件??
  • ????event_set(&evListen,?iSvrFd,?EV_READ|EV_PERSIST,?onAccept,?NULL);??
  • ????//?設(shè)置為base事件??
  • ????event_base_set(base,?&evListen);??
  • ????//?添加事件??
  • ????event_add(&evListen,?NULL);??
  • ??????
  • ????//?事件循環(huán)??
  • ????event_base_dispatch(base);??
  • ??
  • ????return?0;??
  • } ?

  • 三. HTTP服務(wù)器

    ? ?

    C代碼??
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • #include?<unistd.h>??
  • #include?<event.h>??
  • #include?<evhttp.h>??
  • ??
  • void?reqHandler(struct?evhttp_request?*req,void?*arg)??
  • {??
  • ????struct?evbuffer?*buf?=?evbuffer_new();??
  • ??????
  • ????//?發(fā)送響應(yīng)??
  • ????evbuffer_add_printf(buf,?"Thanks?for?the?request");??
  • ????evhttp_send_reply(req,HTTP_OK,"Client",buf);??
  • ??????
  • ????evbuffer_free(buf);??
  • ??????
  • ????return;??
  • }?
  • void http_handle(struct evhttp_request* req, void* arg)
    {
    ??? struct evbuffer* buffer = evbuffer_new();

    ??? // 獲取客戶端請求的URL
    ??? const char* url;
    ??? url = evhttp_request_uri(req);
    ??? evbuffer_add_printf(buffer, "url = %s\n", url);

    ??? // 解析url的參數(shù)(即GET方法的參數(shù))
    ??? struct evkeyvalq params;
    ??? evhttp_parse_query(url, &params);
    ??? evbuffer_add_printf(buffer, "a = %s\n", evhttp_find_header(&params, "a"));
    ??? evbuffer_add_printf(buffer, "b = %s\n", evhttp_find_header(&params, "b"));

    ??? // 設(shè)置HTTP表頭
    ??? evhttp_add_header(req->output_headers, "Server", "mytest http server 0.1");
    ??? evhttp_add_header(req->output_headers, "Content-Type", "text/plain;charset=UTF-8");
    ??? evhttp_add_header(req->output_headers, "Connection", "close");

    ??? // 返回數(shù)據(jù)
    ??? evhttp_send_reply(req, HTTP_OK, "OK", buffer);
    ??? evbuffer_free(buffer);
    }

  • int?main(int?argc,char?**argv)??
  • {??
  • ????short?port?=?8000;??
  • ????const?char?*addr?=?"192.168.1.11";??
  • ????struct?evhttp?*httpserv?=?NULL;??
  • ??
  • ????event_init();??
  • ????????//?啟動http服務(wù)??
  • ????httpserv?=?evhttp_start(addr,port);??
  • ??
  • ????//?設(shè)置回調(diào)??
  • ????evhttp_set_gencb(httpserv,?reqHandler,NULL);??
  • ????printf("Server?started?on?port?%d\n",port);??
  • ??
  • ????event_dispatch();??
  • ??
  • ????return?0;??
  • }??
  • ? ? 瀏覽器訪問:?http://192.168.1.11:8000?會顯示 Thanks for the request




  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • #include?<unistd.h>??
  • #include?<event.h>??
  • #include?<evhttp.h>??
  • ??
  • void?reqHandler(struct?evhttp_request?*req,void?*arg)??
  • {??
  • ????struct?evbuffer?*buf?=?evbuffer_new();??
  • ??????
  • ????//?發(fā)送響應(yīng)??
  • ????evbuffer_add_printf(buf,?"Thanks?for?the?request");??
  • ????evhttp_send_reply(req,HTTP_OK,"Client",buf);??
  • ??????
  • ????evbuffer_free(buf);??
  • ??????
  • ????return;??
  • }?

  • void http_handle(struct evhttp_request* req, void* arg)
    {
    ??? struct evbuffer* buffer = evbuffer_new();

    ??? // 獲取客戶端請求的URL
    ??? const char* url;
    ??? url = evhttp_request_uri(req);
    ??? evbuffer_add_printf(buffer, "url = %s\n", url);

    ??? // 解析url的參數(shù)(即GET方法的參數(shù))
    ??? struct evkeyvalq params;
    ??? evhttp_parse_query(url, &params);
    ??? evbuffer_add_printf(buffer, "a = %s\n", evhttp_find_header(&params, "a"));
    ??? evbuffer_add_printf(buffer, "b = %s\n", evhttp_find_header(&params, "b"));

    ??? // 設(shè)置HTTP表頭
    ??? evhttp_add_header(req->output_headers, "Server", "mytest http server 0.1");
    ??? evhttp_add_header(req->output_headers, "Content-Type", "text/plain;charset=UTF-8");
    ??? evhttp_add_header(req->output_headers, "Connection", "close");

    ??? // 返回數(shù)據(jù)
    ??? evhttp_send_reply(req, HTTP_OK, "OK", buffer);
    ??? evbuffer_free(buffer);
    }

  • int?main(int?argc,char?**argv)??
  • {??
  • ????short?port?=?8000;??
  • ????const?char?*addr?=?"192.168.1.11";??
  • ????struct?evhttp?*httpserv?=?NULL;??
  • ??
  • ????event_init();??
  • ????????//?啟動http服務(wù)??
  • ????httpserv?=?evhttp_start(addr,port);??
  • ??
  • ????//?設(shè)置回調(diào)??
  • ????evhttp_set_gencb(httpserv,?reqHandler,NULL);??
  • ????printf("Server?started?on?port?%d\n",port);??
  • ??
  • ????event_dispatch();??
  • ??
  • ????return?0;??
  • }?

  • 總結(jié)

    以上是生活随笔為你收集整理的libevent简介和使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。