libevent 示例代码

本文介绍了一个使用Libevent实现的服务端程序,通过监听指定端口并处理客户端连接请求,能够读取并回显客户端发送的数据,支持非阻塞模式及错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

server.cpp

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <netinet/in.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/types.h>

#include "event.h"

#define MAX_BUF_LEN 1024 

void read_cb(struct bufferevent *bev, void *arg) {
        char line[MAX_BUF_LEN+1];
        int n;
        evutil_socket_t fd = bufferevent_getfd(bev);

        while (n = bufferevent_read(bev, line, MAX_BUF_LEN), n > 0) {
                line[n] = '\0';
                printf("fd=%u, read line: %s\n", fd, line);
                bufferevent_write(bev, line, n);
                if(strcmp(line, "quit") == 0 || 
                        strcmp(line, "exit") == 0){
                        close(fd);
                }
        }
}

void write_cb(struct bufferevent *bev, void *arg) {
}

void error_cb(struct bufferevent *bev, short event, void *arg) {
        evutil_socket_t fd = bufferevent_getfd(bev);
        printf("fd = %u, ", fd);
        if (event & BEV_EVENT_TIMEOUT) {
                printf("Timed out\n"); //if bufferevent_set_timeouts() called
        }else if (event & BEV_EVENT_EOF) {
                printf("connection closed\n");
        }else if (event & BEV_EVENT_ERROR) {
                printf("some other error\n");
        }
        bufferevent_free(bev);
}

void handleConnection(evutil_socket_t listen_fd, short event_type, void *arg){
        event_base *base = (struct event_base *)arg;
        evutil_socket_t fd;
        sockaddr_in sin;
        socklen_t slen;
        fd = accept(listen_fd, (struct sockaddr *)&sin, &slen);
        if (fd < 0) {
                perror("accept");
                return;
        }
        if (fd > FD_SETSIZE) {
                perror("fd > FD_SETSIZE\n");
                return;
        }

        printf("ACCEPT: fd = %u\n", fd);

        bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
        bufferevent_setcb(bev, read_cb, NULL, error_cb, arg);
        bufferevent_enable(bev, EV_READ|EV_WRITE|EV_PERSIST);
}

int main(int argc, char** argv) {
        event_base *base = event_base_new();
        event *listen_event;
        int listen_fd;
        uint16_t server_port = 9999;
        sockaddr_in server_addr;

        assert(base != NULL);
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
        evutil_make_socket_nonblocking(listen_fd);
        assert(listen_fd != -1);
        memset(&server_addr, 0, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        server_addr.sin_port = htons(server_port);
        bind(listen_fd, (sockaddr*) &server_addr, sizeof(server_addr));
        listen(listen_fd, 16);
        printf("Listening ...\n");

        listen_event = event_new(base, listen_fd, EV_READ|EV_PERSIST, handleConnection, (void*)base);
        event_add(listen_event, NULL);
        event_base_dispatch(base);
        return 0;
}

客户端代码可以参考epoll 示例代码中的client.cpp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值