首页 > 系统相关 >【Linux系统编程】libevent库实现简易tcp服务器

【Linux系统编程】libevent库实现简易tcp服务器

时间:2024-04-14 16:00:11浏览次数:24  
标签:serv lfd addr Linux tcp base libevent include event

libevent库实现简易tcp服务器

流程分析

  1. 创建socket,设置端口复用,绑定四元组,开始监听。
  2. 初始化event_base结构体。
  3. 编写监听事件的回调函数和客户端读事件的回调函数。
  4. 初始化tcp监听事件,并加入event_base中。
  5. 开始event事件处理循环。
  6. 释放所有事件占用资源。
  7. 释放event_base占用资源。

服务端源码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <event2/event.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <cerrno>
#include <unistd.h>

void conncb(evutil_socket_t fd, short events, void *arg);
void readcb(evutil_socket_t fd, short events, void *arg);

int main(int argc, char *argv[]) {
    // 创建socket
    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    
    // 设置端口复用
    int opt = 1;
    setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    // 绑定
    sockaddr_in serv;
    memset(&serv, 0, sizeof(serv));
    serv.sin_addr.s_addr = htonl(INADDR_ANY);
    serv.sin_port = htons(8888);
    serv.sin_family = AF_INET;
    bind(lfd, (sockaddr*)&serv, sizeof(serv));

    // 监听
    listen(lfd, 1024);
    
    // 创建event_base
    event_base *base = event_base_new();
    if (base == nullptr) {
       perror("event_base_new()"); 
       exit(-1);
    }

    // 创建监听文件描述符对应事件
    event *ev = event_new(base, lfd, EV_READ|EV_PERSIST, conncb, base);
    if (ev == nullptr) {
        perror("event_new(lfd)");
        exit(-1);
    }

    // 将新的事件添加到event_base
    event_add(ev, nullptr);

    // 进入事件循环
    event_base_dispatch(base);

    // 释放事件
    event_base_free(base);
    event_free(ev);

    close(lfd);

    return 0;
}

void conncb(evutil_socket_t fd, short events, void *arg) {
    sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);
    int cfd = accept(fd, (sockaddr*)&addr, &addrlen);
    if (cfd == -1) {
        perror("accept");
        exit(-1);
    }
    char ipstr[1024];
    if (nullptr == inet_ntop(AF_INET, &addr.sin_addr.s_addr, ipstr, 1024)) {
        perror("inet_ntop()");
        exit(-1);
    }
    std::cout << "Accept from " << ipstr << ":" << ntohs(addr.sin_port) << " on " << cfd << std::endl;
    
    // 创建客户端监听事件并放进event_base
    event *connev = event_new((event_base*)arg, cfd, EV_READ|EV_PERSIST, readcb, connev);
    if (connev == nullptr) {
        perror("event_new(cfd)");
        exit(-1);
    }
    event_add(connev, 0);
}

void readcb(evutil_socket_t fd, short events, void *arg) {
    int n;
    char buffer[1024];
    memset(buffer, 0, sizeof(buffer));   
    n = read(fd, buffer, sizeof(buffer));
    if (n <= 0) {
        close(fd);
        // 将读事件从event_base移除
        event_del((event*)arg);
    }
    std::cout << "Read from " << fd << ":" << buffer << std::endl;
    write(fd, buffer, n);
}

标签:serv,lfd,addr,Linux,tcp,base,libevent,include,event
From: https://www.cnblogs.com/yangxuanzhi/p/18127438

相关文章

  • Linux-vim文本编辑器-三种模式-vim里的替换
    1.vi和vim命令是linux中强大的文本编辑器,由于Linux系统一切皆文件,而配置一个服务就是在修改其配置文件的参数。vim编辑器是运维工程师必须掌握的一个工具,没有它很多工作都无法完成。vim其实是vi的升级版 2.vim三种工作模式Vim编辑器中设置了三种模式:命令模......
  • Linux文件属性及类型-替换(tr)
    1.##tr只能按照字符一一对应取替换,如果出现相同的字符,那么后面的赋值会将前面的赋值覆盖tr'被替换的内容''替换内容'<文件名可以替换但是文件真正的内容没变[root@localhost~]#tr'tyq''zyx'<1.txtzyxzym[root@localhost~]#cat1.txttyqtym如果不是一一对应就......
  • Linux内核协议栈skb成员
    struct__sk_buff{ __u32len; __u32pkt_type; __u32mark; __u32queue_mapping; __u32protocol; __u32vlan_present; __u32vlan_tci; __u32vlan_proto; __u32priority; __u32ingress_ifindex; __u32ifindex; __u32tc_index; __u32cb[5]; __u32has......
  • 04_NET中使用Redis(ServiceStack.Redis)和Linux中安装Redis
    官网:Redis-TheReal-timeDataPlatformLinux安装Redis: 1.安装gcc安装gccyum-yinstallgcctcl如果出现Complete表示成功查看gcc版本gcc-v 2.升级gcc升级到gcc9.3:yum-yinstallcentos-release-sclyum-yinstalldevtoolset-9-gccdevtoolset-9-gcc-c++......
  • 在Linux中,如何使用脚本进行系统配置和部署?
    在Linux中,使用脚本进行系统配置和部署是一种自动化和标准化环境设置的有效方法。脚本可以简化复杂的安装和配置过程,确保在多个系统或环境中的一致性。以下是使用脚本进行系统配置和部署的一般步骤:1.规划和设计在编写脚本之前,规划你需要执行的任务和步骤。确定脚本需要完成的功......
  • 在Linux中,如何使用LVM管理逻辑卷?
    在Linux中,逻辑卷管理(LVM)是一种灵活的磁盘管理方法,它允许你创建、调整和移动逻辑卷,而无需中断服务。LVM提供了对物理存储资源的抽象层,使得管理大型存储解决方案变得更加容易。以下是使用LVM管理逻辑卷的基本步骤:1.安装LVM工具首先,确保你的系统已经安装了LVM工具,包括lvm2和device......
  • 在Linux中,如何管理磁盘配额?
    在Linux中,管理磁盘配额是一种限制用户或组磁盘使用量的方法,以防止单个用户或组占用过多的磁盘空间,从而影响系统的稳定性和其他用户的正常使用。磁盘配额通常通过文件系统属性或使用专门的配额管理工具来实现。1.使用文件系统配额许多现代文件系统(如ext4、XFS)支持内置的磁盘配额......
  • 在Linux中,如何创建、检查和修复文件系统?
    在Linux中,创建、检查和修复文件系统是磁盘管理和维护的重要部分。以下是使用常用命令行工具进行这些操作的步骤:1.创建文件系统创建分区:使用fdisk或parted命令创建一个新的磁盘分区。sudofdisk/dev/sdx在fdisk提示符下,使用n创建新分区,w写入分区表并退出。格式化分区:......
  • 在Linux中,如何实现文件系统的快照和克隆?
    在Linux中,文件系统快照和克隆是两种用于数据备份和恢复的技术。快照是文件系统在特定时间点的只读副本,而克隆则是快照的可写副本。1.文件系统快照LVM(逻辑卷管理)提供了一种创建文件系统快照的简单方法。快照可以用于数据恢复、备份、升级系统或应用程序等场景。创建逻辑卷:如......
  • 在Windows上部署ArchLinux(WSL)
    在Windows上部署ArchLinux(基于WSL)在开始前请确保你拥有一个Linux环境,以便于后续的步骤顺利地进行。ArchLinux大家应该用过,这个发行版属实需要折腾。但是MicrosoftStore没有提供ArchLinux的WSL版本,所以,才有了这篇文章。2024年4月14日补充:微软商店确实有,但是默认安装在C:......