13、《Libevent中文帮助文档》学习笔记13:Linux下集成、运行libevent

article/2025/9/10 8:42:38

Linux下编译libevent的指导可以参考《4、《Libevent中文帮助文档》学习笔记4:Linux下编译libevent》,完成编译、安装,生成so库后,其他程序即可依赖libevent的so库,使用libevent的功能。

由于没有通过prefix指定安装路径,因此库文件默认安装在/usr/local/lib下,头文件在/usr/local/include下,如下所示:

如图可以看出,libevent的so库存在软链接现象。

集成libevent的源码如下:

/*For sockaddr_in*/
#include <netinet/in.h>
/*For socket functions*/
#include <sys/socket.h>
/*For fcntl*/
#include <fcntl.h>
#include <event2/event.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define MAX_LINE 16384void do_read(evutil_socket_t fd, short events, void*arg);
void do_write(evutil_socket_t fd, short events, void*arg);char rot13_char(char c)
{/* We don’t want to use isalpha here; setting the locale change which characters are considered alphabetical.*/if ((c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M')){return c + 13;}else if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z')){return c - 13;}else{return c;}
}struct fd_state
{char buffer[MAX_LINE];size_t buffer_used;size_t n_written;size_t write_upto;struct event* read_event;struct event* write_event;
};struct fd_state* alloc_fd_state(struct event_base* base, evutil_socket_t fd)
{struct fd_state* state = malloc(sizeof(struct fd_state));if (!state) return NULL;state->read_event = event_new(base, fd, EV_READ | EV_PERSIST, do_read, state);if (!state->read_event){free(state); return NULL;}state->write_event = event_new(base, fd, EV_WRITE | EV_PERSIST, do_write, state);if (!state->write_event){event_free(state->read_event);free(state);return NULL;}state->buffer_used = state->n_written = state->write_upto = 0;assert(state->write_event);return state;
}void free_fd_state(struct fd_state* state)
{event_free(state->read_event);event_free(state->write_event);free(state);
}void do_read(evutil_socket_t fd, short events, void*arg)
{struct fd_state*state = arg;char buf[1024]; int i; ssize_t result;while (1){assert(state->write_event);result = recv(fd, buf, sizeof(buf), 0);if(result <= 0)break;for (i = 0; i < result; ++i){if (state->buffer_used < sizeof(state->buffer))state->buffer[state->buffer_used++] = rot13_char(buf[i]);if (buf[i] == '\n'){assert(state->write_event);event_add(state->write_event, NULL);state->write_upto = state->buffer_used;}}}if (result == 0){free_fd_state(state);}else if (result < 0){if (errno == EAGAIN) // XXXX use evutil macro return ; perror("recv");                 free_fd_state(state);}
} void do_write(evutil_socket_t fd, short events, void*arg)
{struct fd_state*state = arg;while (state->n_written < state->write_upto){ssize_t result = send(fd, state->buffer + state->n_written, state ->write_upto -         state->n_written, 0);if (result < 0){if (errno == EAGAIN) // XXX use evutil macro return ;free_fd_state(state);return;}assert(result != 0);state->n_written += result;}if (state->n_written == state->buffer_used)state->n_written = state->write_upto = state->buffer_used = 1;event_del(state->write_event);
}void do_accept(evutil_socket_t listener, short event, void*arg)
{struct event_base*base = arg;struct sockaddr_storage ss;socklen_t slen =sizeof(ss);int fd = accept(listener, (struct sockaddr*) &ss, &slen);if (fd < 0){// XXXX eagain??perror("accept");}else if (fd > FD_SETSIZE){close(fd); // XXX replace all closes with EVUTIL_CLOSESOCKET}else{struct fd_state*state;evutil_make_socket_nonblocking(fd);state =alloc_fd_state(base, fd);assert(state);/*XXX err */assert(state->write_event);event_add(state->read_event, NULL);}
}void run(void)
{struct event_base* base = event_base_new();if (!base) return;/* 创建socket */struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_addr.s_addr = 0;sin.sin_port = htons(40713);evutil_socket_t listener = socket(AF_INET, SOCK_STREAM, 0);/* 设置为非阻塞 */evutil_make_socket_nonblocking(listener);#ifndef WIN32{int one = 1;setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));}
#endif/* 绑定socket */if (bind(listener, (struct sockaddr*) &sin, sizeof(sin)) < 0){perror("bind");return;}/* 启动监听 */if (listen(listener, 16) < 0){perror("listen");return;}struct event* listener_event = event_new(base, listener, EV_READ | EV_PERSIST, do_accept,(void*)base);/*XXX check it*/event_add(listener_event, NULL);event_base_dispatch(base);
}int main(int c, char**v)
{setvbuf(stdout, NULL, _IONBF, 0);run();return 0;
}

编写完源码后,接下去的工作就是编译。使用如下命令进行编译:

gcc -o server server.c -levent_core

由于libevent安装在/usr/local/lib目录下,因为不需要指定依赖路径,直接指定依赖libevent_core.so即可。

编译成功后,执行如下命令,运行可执行文件sever:

./server

出现如下报错:

./server: error while loading shared libraries: libevent_core-2.1.so.6: cannot open shared object file: No such file or directory

即无法加载可执行文件server的依赖库libevent_core-2.1.so.6,看到这里有点懵了,编译时,指定的依赖库文件明明是libevent_core.so,为什么在这里变为libevent_core-2.1.so.6,猜想可能原因是-levent_core匹配到/usr/local/lib/目录下的libevent_core-2.1.so.6了。但是,无论是libevent_core-2.1.so.6,还是libevent_core.so,都只是一个文件软链接,最终指向的都是libevent_core-2.1.so.6.0.2。

即使server依赖的是libevent_core-2.1.so.6,但是为啥运行报错了?/usr/local/lib目录下是有这个文件的啊?因此,通过如下命令查看server的依赖库信息:

ldd server

依赖库如下所示:

        linux-vdso.so.1 =>  (0x00007ffd4f78b000)
        libevent_core-2.1.so.6 => not found
        libc.so.6 => /lib64/libc.so.6 (0x00007fa2a92b5000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fa2a9682000)

发现确实无法加载到libevent_core-2.1.so.6。通过如下命令,查看server的库搜索路径:

LD_DEBUG=libs ./server -v

搜索路径为:

     20398:     find library=libevent_core-2.1.so.6 [0]; searching
     20398:      search cache=/etc/ld.so.cache
     20398:      search path=/lib64/tls/x86_64:/lib64/tls:/lib64/x86_64:/lib64:/usr/lib64/tls/x86_64:/usr/lib64/tls:/usr/lib64/x86_64:/usr/lib64                (system search path)
     20398:       trying file=/lib64/tls/x86_64/libevent_core-2.1.so.6
     20398:       trying file=/lib64/tls/libevent_core-2.1.so.6
     20398:       trying file=/lib64/x86_64/libevent_core-2.1.so.6
     20398:       trying file=/lib64/libevent_core-2.1.so.6
     20398:       trying file=/usr/lib64/tls/x86_64/libevent_core-2.1.so.6
     20398:       trying file=/usr/lib64/tls/libevent_core-2.1.so.6
     20398:       trying file=/usr/lib64/x86_64/libevent_core-2.1.so.6
     20398:       trying file=/usr/lib64/libevent_core-2.1.so.6
     20398:
./server: error while loading shared libraries: libevent_core-2.1.so.6: cannot open shared object file: No such file or directory

发现搜索路径中,并没有/usr/local/lib,自然是无法加载到libevent_core-2.1.so.6。因此,将libevent_core-2.1.so.6拷贝到搜索路径下即可。也可以通过如下命令,为/usr/local/lib/libevent_core-2.1.so.6在/usr/lib64/下创建一个软链接:

ln -s /usr/local/lib/libevent_core-2.1.so.6 /usr/lib64/libevent_core-2.1.so.6

 


http://chatgpt.dhexx.cn/article/7WaPcDOu.shtml

相关文章

libevent 编译与安装 (WIN10 visual studio2019, ubuntu,centos)

文章目录 一、准备安装包二、编译与安装编译zlib编译openssl编译libevent 三、libevent集成zlib测试程序修改编译&#xff08;可选&#xff09;四、测试程序五、linux(ubuntu)测试安装依赖环境&#xff0c;依次编译zlib,openssl,libeventwindows与linux共享文件夹&#xff08;使…

Libevent 学习一:Libevent 源码编译

文章目录 Libevent 学习一&#xff1a;Libevent 源码编译Libevent Windows 编译Windows 编译环境安装 Visual Studio Community 2015安装 zlib安装 OpenSSL安装 Libeventcmake 安装 LibeventLibevent 测试程序 Libevent Linux编译CentOS 7 安装 LibeventLibevent 测试程序 Libe…

libevent mysql_libevent安装总结

1.先用&#xff1a;ls -al /usr/lib | grep libevent 查看是否已安装&#xff1b;如果已安装且版本低于1.3&#xff0c;则先通过&#xff1a;rpm -e libevent —nodeps进行卸载。 2.下载libevent安装包&#xff1a;libevent-2.0.18-stable.tar.gz。 wget https://github.com/do…

在window用vcpkg安装libevent

参考readme https://github.com/microsoft/vcpkg/blob/master/README_zh_CN.md 使用的PackageManager方式安装&#xff0c; Package Managers 下载 vcpkg 依赖管理包 git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.bat ./vcpkg integrate…

libevent实践01:准备源码、搭建项目、编译脚本和入门例子

编译源码 libevent是一个Reactor事件库。 我的理解&#xff0c;就是封装了select、epoll、poll的函数库。有使用select&#xff0c;poll&#xff0c;epoll的需求就可以使用的。 官网地址&#xff1a;https://libevent.org/ 下载源码&#xff1a; https://github.com/libev…

libevent(1)windows下安装libevent

Socket通信库libevent成熟、稳定、性能高&#xff0c;在unix和windows下都能使用&#xff0c;在证券交易领域也有不少成功的应用&#xff0c;已经用事实证明是非常棒的socket通信库。对我们目前交易系统的unix重构来说&#xff0c;是比较合适的选择 –– 坑少、在证券交易项目中…

Libevent库的学习

目录 Libevent 概述 Libevent 使用模型 使用Libevent的基本流程&#xff1a; libevent 的核心&#xff0c;event 事件 1. 创建一个事件event 2. 释放event_free 3. 注册event 4. 信号事件 5. 销毁event_base Libevent 结构图 使用libevent库去实现tcp服务器 Libev…

编译libevent

本文记录在win10编译libevent的过程 1.编译前准备zlib,openssl zlib网址 http://www.zlib.net/ 下载源码解压缩 打开vs的dos窗口 32位选择32位窗口这里选择64位,cd 到解压后的文件夹 执行 nmake /f win32/Makefile.msc 执行后可以看到目录下有lib文件和dll文件和测试文件…

libevent简要介绍

libevent库 开源。精简。跨平台&#xff08;Windows、Linux、Maxos、unix&#xff09;。专注于网络通信。 源码包安装&#xff1a; ./configure 检查安装环境 生成makefile make 生成.o和可执行文件 sudo make install …

Libevent库的简介

一、libevent是什么 Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库&#xff0c;主要有以下几个亮点&#xff1a;事件驱动&#xff08; event-driven&#xff09;&#xff0c;高性能;轻量级&#xff0c;专注于网络&#xff0c;不如 ACE 那么臃肿庞大&#xff1b…

libevent库学习(1)

一、初识 1、libevent介绍 Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库&#xff0c;主要有以下几个亮点&#xff1a;事件驱动&#xff08; event-driven&#xff09;&#xff0c;高性能;轻量级&#xff0c;专注于网络&#xff0c;不如 ACE 那么臃肿庞大&…

详解Libevent网络库

项目中要用到libevent&#xff0c;所以就自学了libevent&#xff0c;参考资料为张亮的《libevent源码深度剖析》和《linux高性能服务器编程》 Libevent简介 Libevent是开源社区一款高性能的I/O框架库&#xff0c;其具有如下特点&#xff1a; 1.跨平台支持。Libevent支持Linu…

Libevent库的介绍与应用

Libevent库 Libevent概述Libevent使用模型Libevent库使用示例Libevent事件类型和框架结构使用Libevent完成tcp服务端 Libevent概述 Libevent是开源社区的一款高性能的I/O框架库&#xff0c;使用Libevent的著名案例有&#xff1a;高性能的分布式内存对象缓存软件memcached,Goog…

Linux c 开发 - libevent

目录 一、event_base 1. 创建event_base 2. 查看IO模型 3. 销毁event_base 4. 事件循环 event loop 5. event_base的例子 二、event 事件 1. 创建一个事件event 2. 释放event_free 3. 注册event 4.event_assign 5. 信号事件 6. event细节 三、Socket实例 四、Bu…

安装svn客户端

下载地址 下载 TortoiseSVN 我的网盘地址&#xff1a; 百度网盘 请输入提取码 提取码&#xff1a; em9s 1、安装客户端 双击运行&#xff1a; 点击【next】 点击【next】 选择好路径后&#xff0c;点击【next】 点击【install】安装 点击【finish】完成安装。安装完成后重…

SVN客户端配置--客户端

一、使用客户端软件连接SVN服务器 在项目文件夹中单击右键–>TortoiseSVN–>Repo-browser,并在弹出框中贴入URL&#xff08;svn://服务器IP&#xff09; 在图中指定的位置单击右键选择checkput 点击OK点击OK SVN的三大指令 指令名称Checkout①连接到SVN服务器②更新服务…

SVN客户端(TortoiseSVN)安装及使用说明

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; SVN客户端(TortoiseSVN)安装及使用说明 ⏱️ 创作时间&#xff1a; 20…

ubuntu搭建SVN客户端,右击提交或更新

有时候我们会在Linux系统上搞开发&#xff0c;项目在SVN上&#xff0c;不搭建SVN环境搞起来比较麻烦&#xff0c;不用其他软件为载体实现右击提交更新等其他操作&#xff0c;不使用VsCode,IDE全家桶等为载体搭建插件形式的SVN&#xff0c;完全独立搭建 1&#xff1a;安装SVN客…

SVN客户端下载及安装

SVN客户端地址&#xff1a;https://osdn.net/projects/tortoisesvn/# 方法/步骤 官网下载tortoisesvn&#xff0c;下载完成之后&#xff0c;如下图所示&#xff1a; 点击安装进入安装界面&#xff0c;点击接受协议&#xff0c;如下图所示&#xff1a; 选择安装的地址&…

【转】Ubuntu中SVN客户端安装+使用

转自&#xff1a;Ubuntu中SVN客户端安装使用_三少GG-CSDN博客 1、 安装 svn客户端&#xff1a; apt-get install subversion&#xff0c;然后根据提示一步一步&#xff0c;就完成了 svn的安装。当然&#xff0c;也可以源码安装 svn&#xff0c;下载 subversion 一个最新版本的源…