日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Libevent(5)— 連接監(jiān)聽器

系統(tǒng) 2345 0

轉(zhuǎn)自:http://name5566.com/4220.html

?

參考文獻(xiàn)列表:
http://www.wangafu.net/~nickm/libevent-book/

此文編寫的時候,使用到的 Libevent 為 2.0.21

Libevent 提供了連接監(jiān)聽器 evconnlistener

創(chuàng)建 evconnlistener 實(shí)例

  1. // 連接監(jiān)聽器回調(diào)函數(shù)原型
  2. typedef void (* evconnlistener_cb )(
  3. struct evconnlistener * listener ,
  4. // 新的 socket
  5. evutil_socket_t sock ,
  6. // 新的 socket 對應(yīng)的地址
  7. struct sockaddr * addr ,
  8. int len ,
  9. // 用戶自定義數(shù)據(jù)
  10. void * ptr
  11. );
  12. ?
  13. // 創(chuàng)建一個新的連接監(jiān)聽器
  14. struct evconnlistener * evconnlistener_new (
  15. struct event_base * base ,
  16. // 一個新的連接到來時此回調(diào)被調(diào)用
  17. evconnlistener_cb cb ,
  18. // 用戶自定義數(shù)據(jù),會被傳遞給 cb 回調(diào)函數(shù)
  19. void * ptr ,
  20. // 連接監(jiān)聽器的選項(xiàng)(下面會詳細(xì)談到)
  21. unsigned flags ,
  22. // 為標(biāo)準(zhǔn)的 listen 函數(shù)的 backlog 參數(shù)
  23. // 如果為負(fù)數(shù),Libevent 將嘗試選擇一個合適的值
  24. int backlog ,
  25. // socket
  26. // Libevent 假定此 socket 已經(jīng)綁定
  27. evutil_socket_t fd
  28. );
  29. ?
  30. // 創(chuàng)建一個新的連接監(jiān)聽器
  31. // 大多數(shù)參數(shù)含義同于 evconnlistener_new
  32. struct evconnlistener * evconnlistener_new_bind (
  33. struct event_base * base ,
  34. evconnlistener_cb cb ,
  35. void * ptr ,
  36. unsigned flags ,
  37. int backlog ,
  38. // 指定需要綁定的 socket 地址
  39. const struct sockaddr * sa ,
  40. int socklen
  41. );

連接監(jiān)聽器的常用選項(xiàng)如下:

  1. LEV_OPT_CLOSE_ON_FREE
    當(dāng)關(guān)閉連接監(jiān)聽器其底層 socket 也被自動釋放
  2. LEV_OPT_REUSEABLE
    設(shè)置 socket 綁定的地址可以重用
  3. LEV_OPT_THREADSAFE
    設(shè)置連接監(jiān)聽器為線程安全的

釋放連接監(jiān)聽器

  1. void evconnlistener_free ( struct evconnlistener * lev );

錯誤檢測
如果連接監(jiān)聽器出錯,我們可以得到通知:

  1. // 連接監(jiān)聽器錯誤回調(diào)函數(shù)原型
  2. typedef void (* evconnlistener_errorcb )( struct evconnlistener * lis , void * ptr );
  3. ?
  4. // 為連接監(jiān)聽器設(shè)置錯誤回調(diào)函數(shù)
  5. void evconnlistener_set_error_cb ( struct evconnlistener * lev ,
  6. evconnlistener_errorcb errorcb );

一個詳細(xì)的范例(echo 服務(wù)器)

    1. #include <event2/listener.h>
    2. #include <event2/bufferevent.h>
    3. #include <event2/buffer.h>
    4. ?
    5. #include <arpa/inet.h>
    6. ?
    7. #include <string.h>
    8. #include <stdlib.h>
    9. #include <stdio.h>
    10. #include <errno.h>
    11. ?
    12. // 讀取回調(diào)函數(shù)
    13. static void
    14. echo_read_cb ( struct bufferevent * bev , void * ctx )
    15. {
    16. struct evbuffer * input = bufferevent_get_input ( bev );
    17. struct evbuffer * output = bufferevent_get_output ( bev );
    18. ?
    19. // 將輸入緩沖區(qū)的數(shù)據(jù)直接拷貝到輸出緩沖區(qū)
    20. evbuffer_add_buffer ( output , input );
    21. }
    22. ?
    23. // 事件回調(diào)函數(shù)
    24. static void
    25. echo_event_cb ( struct bufferevent * bev , short events , void * ctx )
    26. {
    27. if ( events & BEV_EVENT_ERROR )
    28. perror ( "Error from bufferevent" );
    29. if ( events & ( BEV_EVENT_EOF | BEV_EVENT_ERROR )) {
    30. bufferevent_free ( bev );
    31. }
    32. }
    33. ?
    34. // 連接監(jiān)聽器回調(diào)函數(shù)
    35. static void
    36. accept_conn_cb ( struct evconnlistener * listener ,
    37. evutil_socket_t fd , struct sockaddr * address , int socklen ,
    38. void * ctx )
    39. {
    40. // 為新的連接分配并設(shè)置 bufferevent
    41. struct event_base * base = evconnlistener_get_base ( listener );
    42. struct bufferevent * bev = bufferevent_socket_new (
    43. base , fd , BEV_OPT_CLOSE_ON_FREE );
    44. ?
    45. bufferevent_setcb ( bev , echo_read_cb , NULL , echo_event_cb , NULL );
    46. ?
    47. bufferevent_enable ( bev , EV_READ | EV_WRITE );
    48. }
    49. ?
    50. // 連接監(jiān)聽器錯誤回調(diào)函數(shù)
    51. static void
    52. accept_error_cb ( struct evconnlistener * listener , void * ctx )
    53. {
    54. struct event_base * base = evconnlistener_get_base ( listener );
    55. // 獲取到錯誤信息
    56. int err = EVUTIL_SOCKET_ERROR ();
    57. fprintf ( stderr , "Got an error %d (%s) on the listener. "
    58. "Shutting down.\n" , err , evutil_socket_error_to_string ( err ));
    59. ?
    60. // 退出事件循環(huán)
    61. event_base_loopexit ( base , NULL );
    62. }
    63. ?
    64. int
    65. main ( int argc , char ** argv )
    66. {
    67. struct event_base * base ;
    68. struct evconnlistener * listener ;
    69. struct sockaddr_in sin ;
    70. ?
    71. int port = 9876 ;
    72. ?
    73. if ( argc > 1 ) {
    74. port = atoi ( argv [ 1 ]);
    75. }
    76. if ( port <= 0 || port > 65535 ) {
    77. puts ( "Invalid port" );
    78. return 1 ;
    79. }
    80. ?
    81. base = event_base_new ();
    82. if (! base ) {
    83. puts ( "Couldn't open event base" );
    84. return 1 ;
    85. }
    86. ?
    87. memset (& sin , 0 , sizeof ( sin ));
    88. sin . sin_family = AF_INET ;
    89. sin . sin_addr . s_addr = htonl ( 0 );
    90. sin . sin_port = htons ( port );
    91. ?
    92. listener = evconnlistener_new_bind ( base , accept_conn_cb , NULL ,
    93. LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE , - 1 ,
    94. ( struct sockaddr *) & sin , sizeof ( sin ));
    95. if (! listener ) {
    96. perror ( "Couldn't create listener" );
    97. return 1 ;
    98. }
    99. evconnlistener_set_error_cb ( listener , accept_error_cb );
    100. ?
    101. event_base_dispatch ( base );
    102. return 0 ;
    103. }

Libevent(5)— 連接監(jiān)聽器


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 达州市| 金湖县| 囊谦县| 军事| 和顺县| 邻水| 遂宁市| 荃湾区| 屯门区| 仙桃市| 上高县| 通河县| 旬邑县| 永新县| 新郑市| 库尔勒市| 曲水县| 海安县| 昔阳县| 东至县| 阿瓦提县| 和静县| 武陟县| 土默特右旗| 建水县| 澎湖县| 宁陕县| 叙永县| 焉耆| 穆棱市| 辽宁省| 铁力市| 阜宁县| 星座| 深水埗区| 夏河县| 仁寿县| 化德县| 唐河县| 永年县| 荥经县|