精品国产一区在线_av无码中文字幕无码王_天海翼三点刺激高潮不停_好硬好大好爽视频_欧美高清一区三区在线专区_香蕉黄色片

嵌入式開發必備:開源事件驅動庫 libevent

上一篇我們分享了:libevhtp——一款專為嵌入式系統設計的開源HTTP庫!,libevhtp依賴于libevent。這篇文章我們一起來了解libevent。

一、libevent 簡介

libevent 是一個開源的、輕量級的跨平臺事件驅動庫:

Github倉庫地址:https://github.com/libevent/libevent

libevent 的源碼結構清晰,主要分為以下幾個核心模塊:

libevent/├── event.c                
# 事件核心邏輯├── epoll.c               
# Linux epoll 后端實現├── kqueue.c              
# BSD kqueue 后端實現├── select.c              
# 通用 select 后端實現├── bufferevent.c         
# 緩沖區事件處理├── evhttp.c              
# HTTP 協議處理├── evdns.c               
# DNS 解析模塊├── evthread.c            
# 線程支持├── evutil.c              
# 工具函數

它封裝了多種操作系統的 I/O 多路復用機制(如 epoll、kqueue、select 等),提供了統一的事件處理接口,極大簡化了異步網絡編程的復雜度。

1. 核心特性

  • 跨平臺支持:原生支持 Linux、Windows、BSD 等多種操作系統,甚至在嵌入式系統上也能運行
  • 高性能 I/O 模型:自動適配底層最優的 I/O 多路復用機制(epoll/kqueue 優先)
  • 輕量級設計:核心代碼簡潔高效,資源占用低,非常適合嵌入式場景
  • 豐富的功能組件:包含 HTTP 服務器、DNS 解析、SSL 支持等實用模塊
  • 線程安全:提供完善的線程安全機制,支持多線程環境下的事件處理

2. 優缺點分析

二、libevent實戰

1. 源碼獲取與編譯

# 克隆源碼倉庫
git clone https://github.com/libevent/libevent.git
cd libevent

# 創建編譯目錄
mkdir build && cd build

# 使用 CMake 配置(嵌入式平臺需指定交叉編譯工具鏈)
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local/libevent

# 編譯
make -j16

# 安裝到指定目錄
sudo make install

2. 簡單的 TCP 服務器

下面是一個基于 libevent 的簡單 TCP 服務器示例,實現了接收客戶端連接并回顯數據的功能:

#include 
#include 
#include 
#include  
#include 
#include 
#include 
#include 
#include 


/* 客戶端連接處理回調函數 */
void client_read_cb(struct bufferevent *bev, void *ctx) {
    char buffer[1024];
    int len;
    
    /* 從緩沖區讀取數據 */
    len = bufferevent_read(bev, buffer, sizeof(buffer) - 1);
    if (len <= 0) {
        printf("客戶端連接關閉\n");
        bufferevent_free(bev);
        return;
    }
    
    buffer[len] = '\0';
    printf("收到客戶端數據: %s", buffer);
    
    /* 將數據回顯給客戶端 */
    bufferevent_write(bev, buffer, len);
}

/* 客戶端連接錯誤處理回調 */
void client_event_cb(struct bufferevent *bev, short events, void *ctx) {
    if (events & BEV_EVENT_EOF) {
        printf("客戶端斷開連接\n");
    } elseif (events & BEV_EVENT_ERROR) {
        printf("客戶端發生錯誤\n");
    } elseif (events & BEV_EVENT_CONNECTED) {
        printf("客戶端連接成功\n");
    }
    bufferevent_free(bev);
}

/* 新客戶端連接處理回調 */
void accept_conn_cb(struct evconnlistener *listener, evutil_socket_t sock,
                    struct sockaddr *addr, int len, void *ctx) {
    struct event_base *base = evconnlistener_get_base(listener);
    struct sockaddr_in *sin = (struct sockaddr_in *)addr;
    char client_ip[INET_ADDRSTRLEN];
    
    /* 轉換客戶端IP地址格式 */
    inet_ntop(AF_INET, &(sin->sin_addr), client_ip, INET_ADDRSTRLEN);
    printf("新客戶端連接: %s:%d\n", client_ip, ntohs(sin->sin_port));
    
    /* 創建緩沖區事件 */
    struct bufferevent *bev = bufferevent_socket_new(base, sock, BEV_OPT_CLOSE_ON_FREE);
    if (!bev) {
        printf("創建緩沖區事件失敗\n");
        return;
    }
    
    /* 設置回調函數 */
    bufferevent_setcb(bev, client_read_cb, NULL, client_event_cb, NULL);
    
    /* 啟用讀寫事件 */
    bufferevent_enable(bev, EV_READ | EV_WRITE);
}

/* 錯誤處理回調 */
void accept_error_cb(struct evconnlistener *listener, void *ctx) {
    struct event_base *base = evconnlistener_get_base(listener);
    int err = EVUTIL_SOCKET_ERROR();
    printf("監聽錯誤: %s\n", evutil_socket_error_to_string(err));
    
    event_base_loopexit(base, NULL);
}

int main(int argc, char **argv) {
    struct event_base *base;
    struct evconnlistener *listener;
    struct sockaddr_in sin;
    int port = 9999;
    
    /* 初始化事件基 */
    base = event_base_new();
    if (!base) {
        printf("創建事件基失敗\n");
        return1;
    }
    
    /* 配置監聽地址 */
    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = htonl(INADDR_ANY);
    sin.sin_port = htons(port);
    
    /* 創建監聽套接字 */
    listener = evconnlistener_new_bind(base, accept_conn_cb, NULL,
                                      LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
                                      -1, (struct sockaddr *)&sin, sizeof(sin));
    if (!listener) {
        printf("創建監聽失敗\n");
        event_base_free(base);
        return1;
    }
    
    /* 設置監聽錯誤回調 */
    evconnlistener_set_error_cb(listener, accept_error_cb);
    
    printf("服務器啟動,監聽端口: %d\n", port);
    
    /* 進入事件循環 */
    event_base_dispatch(base);
    
    /* 清理資源 */
    evconnlistener_free(listener);
    event_base_free(base);
    
    return0;
}

編譯命令:

gcc -o tcp_server tcp_server.c -I/path/to/libevent/include -L/path/to/libevent/lib -levent -Wl,-rpath=/path/to/libevent/lib

Telnet協議是TCP/IP協議族中的一員,是Internet遠程登陸服務的標準協議和主要方式。telnet命令可以用來確定遠程服務的狀態,比如確定遠程服務器的某個端口是否能訪問。

重要部分:

  • 事件基 (event_base):整個事件處理的核心,管理事件循環和事件分發
  • 連接監聽器 (evconnlistener):封裝了 TCP 服務器的監聽邏輯,簡化連接處理
  • 緩沖區事件 (bufferevent):提供了帶緩沖區的事件處理,自動管理數據讀寫
  • 回調函數機制:libevent 采用異步回調模式,避免阻塞式編程
聲明:本內容為作者獨立觀點,不代表電子星球立場。未經允許不得轉載。授權事宜與稿件投訴,請聯系:editor@netbroad.com
覺得內容不錯的朋友,別忘了一鍵三連哦!
贊 3
收藏 3
關注 30
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧
主站蜘蛛池模板: 美女脱个精光扒开隐私自己玩 | 久久精品黄色 | 亚洲av无码专区国产乱码不卡 | 久久av中文 | 僵尸启示录在线 | 大地资源中文在线观看免费高清电视剧 | 国产免费午夜福利在线播放92 | 免费精品视频一区二区 | 国产精品欧美在线视频 | AV人摸人人人澡人人超碰手机版 | 东北一级片 | 在线不卡日本v二区707 | www.在线国产| 亚洲第一区欧美国产综合86 | 亚洲性无码av在线欣赏网 | 国产永久黄网站色视频免费 | 野花韩国高清免费视频6 | 成年黄色网| 日本在线视频WWW色影响 | 欧洲精品色 | 优酷在线观看 | 中国免费毛片 | 美国av一级| 99在线视频免费观看 | 夜间视频在线观看 | 欧美日韩亚洲免费 | "97国产婷婷综合在线视频 " | 波多野结衣 黑人 | 亚洲看片wwwwf5con | 久久久久无码精品国产H动漫 | 免费看无码毛视频成片 | 亚洲人777| 伊人伦理 | 欧美日韩国产中文 | 国产亚洲精品久久久久久久久久 | 内射高潮享受视频在线观看 | 国产日韩欧美另类 | 美女久久网站 | 成人三级a视频在线观看 | 亚洲精品视频二区 | 日本在线a视频 |