验证是否已经安装Libevent
[weblogic@localhost opt]$ ls -al /usr/lib | grep libevent
下载地址:
libevent
[root@localhost opt]# tar -zxvf libevent-2.1.12-stable.tar.gz
/usr/local/libevent
检测安装环境,例如内存空间是否足够,生成makefile文件。
[root@localhost libevent-2.1.8-stable]# ./configure
可以指定具体路径,这样安装的时候,将统一安装到指定路径 例如:./configure --prefix=/usr/local/libevent:
[root@localhost libevent-2.1.8-stable]# ./configure -prefix=/usr/local/libevent
生成.o文件和可执行文件
[root@localhost libevent-2.1.8-stable]# make
将必要的资源安装到系统的指定目录
[root@localhost libevent-2.1.8-stable]# make install
第1~3步就不用说了,常规准备步骤而已,问题出在第4步配置的时候,此时出现错误:
configure: error: openssl is a must but can not be found. You should add the directory containing ‘openssl.pc’ to the ‘PKG_CONFIG_PATH’ environment variable, or set ‘CFLAGS’ and ‘LDFLAGS’ directly for openssl, or use `–disable-openssl’ to disable support for openssl encryption
解决方式:ubuntu 平台安装 libssl-dev
libssl-dev安装步骤
# sudo apt-get update
# sudo apt-get install libssl-dev
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/sbin" ldconfig -n /usr/local/libevent/lib
----------------------------------------------------------------------
Libraries have been installed in:
/usr/local/libevent/lib
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the 'LD_RUN_PATH' environment variable
during linking
- use the '-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to '/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
/usr/bin/mkdir -p '/usr/local/libevent/include'
/usr/bin/install -c -m 644 include/evdns.h include/event.h include/evhttp.h include/evrpc.h include/evutil.h '/usr/local/libevent/include'
/usr/bin/mkdir -p '/usr/local/libevent/include/event2'
/usr/bin/install -c -m 644 include/event2/buffer.h include/event2/buffer_compat.h include/event2/bufferevent.h include/event2/bufferevent_compat.h include/event2/bufferevent_struct.h include/event2/dns.h include/event2/dns_compat.h include/event2/dns_struct.h include/event2/event.h include/event2/event_compat.h include/event2/event_struct.h include/event2/http.h include/event2/http_compat.h include/event2/http_struct.h include/event2/keyvalq_struct.h include/event2/listener.h include/event2/rpc.h include/event2/rpc_compat.h include/event2/rpc_struct.h include/event2/tag.h include/event2/tag_compat.h include/event2/thread.h include/event2/util.h include/event2/visibility.h include/event2/bufferevent_ssl.h '/usr/local/libevent/include/event2'
/usr/bin/mkdir -p '/usr/local/libevent/include/event2'
/usr/bin/install -c -m 644 include/event2/event-config.h '/usr/local/libevent/include/event2'
/usr/bin/mkdir -p '/usr/local/libevent/lib/pkgconfig'
/usr/bin/install -c -m 644 libevent.pc libevent_core.pc libevent_extra.pc libevent_pthreads.pc libevent_openssl.pc '/usr/local/libevent/lib/pkgconfig'
make[2]: Leaving directory '/home/libevent-2.1.12-stable'
make[1]: Leaving directory '/home/libevent-2.1.12-stable'
root@iZm5e9phbzdxx0lysrv9t2Z:/home/libevent-2.1.12-stable#
如果在配置阶段没有指定安装目录,则
如果在配置阶段没有指定安装目录,例如:./configure --prefix=/usr/local/libevent,则
添加动态链接库:
root@iZm5e9phbzdxx0lysrv9t2Z:/home/libevent-2.1.12-stable# export LD_LIBRARY_PATH=/usr/local/libevent/lib
cd sample ,进入安装文件夹的samle目录,随便测试一个demo,这里测试helloworld.c。
/*
This example program provides a trivial server program that listens for TCP
connections on port 9995. When they arrive, it writes a short message to
each client connection, and closes each connection once it is flushed.
Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
*/
#include
#include
#include
#include
#ifndef _WIN32
#include
# ifdef _XOPEN_SOURCE_EXTENDED
# include
# endif
#include
#endif
#include
#include
#include
#include
#include
static const char MESSAGE[] = "Hello, World!\n";
static const int PORT = 9995;
static void listener_cb(struct evconnlistener *, evutil_socket_t,
struct sockaddr *, int socklen, void *);
static void conn_writecb(struct bufferevent *, void *);
static void conn_eventcb(struct bufferevent *, short, void *);
static void signal_cb(evutil_socket_t, short, void *);
int
main(int argc, char **argv)
{
struct event_base *base;
struct evconnlistener *listener;
struct event *signal_event;
struct sockaddr_in sin = {0};
#ifdef _WIN32
WSADATA wsa_data;
WSAStartup(0x0201, &wsa_data);
#endif
base = event_base_new();
if (!base) {
fprintf(stderr, "Could not initialize libevent!\n");
return 1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
(struct sockaddr*)&sin,
sizeof(sin));
if (!listener) {
fprintf(stderr, "Could not create a listener!\n");
return 1;
}
signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);
if (!signal_event || event_add(signal_event, NULL)<0) {
fprintf(stderr, "Could not create/add a signal event!\n");
return 1;
}
event_base_dispatch(base);
evconnlistener_free(listener);
event_free(signal_event);
event_base_free(base);
printf("done\n");
return 0;
}
static void
listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
struct sockaddr *sa, int socklen, void *user_data)
{
struct event_base *base = user_data;
struct bufferevent *bev;
bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
if (!bev) {
fprintf(stderr, "Error constructing bufferevent!");
event_base_loopbreak(base);
return;
}
bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL);
bufferevent_enable(bev, EV_WRITE);
bufferevent_disable(bev, EV_READ);
bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
}
static void
conn_writecb(struct bufferevent *bev, void *user_data)
{
struct evbuffer *output = bufferevent_get_output(bev);
if (evbuffer_get_length(output) == 0) {
printf("flushed answer\n");
bufferevent_free(bev);
}
}
static void
conn_eventcb(struct bufferevent *bev, short events, void *user_data)
{
if (events & BEV_EVENT_EOF) {
printf("Connection closed.\n");
} else if (events & BEV_EVENT_ERROR) {
printf("Got an error on the connection: %s\n",
strerror(errno));/*XXX win32*/
}
/* None of the other events can happen here, since we haven't enabled
* timeouts */
bufferevent_free(bev);
}
static void
signal_cb(evutil_socket_t sig, short events, void *user_data)
{
struct event_base *base = user_data;
struct timeval delay = { 2, 0 };
printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");
event_base_loopexit(base, &delay);
}
gcc helloworld.c -o helloworld //error
此时会报错,因为需要加入libevent库。即完整的命令为
gcc helloworld.c -o helloworld -l event //去掉lib和后缀.so(动态库)就是库名.
gcc helloworld.c -o helloworld -I /usr/local/libevent/include/ -L /usr/local/libevent/lib -l event //去掉lib和后缀.so(动态库)就是库名.
其中:
root@iZm5e9phbzdxx0lysrv9t2Z:/home/libevent-2.1.12-stable/sample# ls
dns-example hello-world http-connect.c https_client-openssl_hostname_validation.o le-proxy.c signal-test.o
dns-example.c hello-world.c http-connect.o http-server le_proxy-le-proxy.o time-test
dns-example.o hello-world.o https-client http-server.c openssl_hostname_validation.c time-test.c
event-read-fifo hostcheck.c https-client.c http-server.o openssl_hostname_validation.h time-test.o
event-read-fifo.c hostcheck.h https_client-hostcheck.o include.am signal-test
event-read-fifo.o http-connect https_client-https-client.o le-proxy signal-test.c
root@iZm5e9phbzdxx0lysrv9t2Z:/home/libevent-2.1.12-stable/sample# ./hello-world
使用下面命令模拟客户端连接到服务端
nc 127.0.0.1 9995 //libevent默认端口
至此,libevent已经成功安装完成。
如果是使用Makelist,同样的也需要指定头文件目录和链接库目录,如下:
cmake_minimum_required(VERSION 3.12)
project(mytest)
set(CMAKE_CXX_STANDARD 14)
include_directories(/usr/local/libevent/include) #指定头文件搜索路径
LINK_DIRECTORIES(/usr/local/libevent/lib) #指定库文件搜索路径
add_executable(mytest main.cpp)
target_link_libraries(mytest libevent.a) #链接库
简单的先编译一个文件 01_getmethods.c
//01_getmethods.c
#include
#include
int main()
{
char ** methods = event_get_supported_methods();//获取libevent后端支持的方法
int i =0;
for(i = 0;methods[i] != NULL ;i++)
{
printf("%s\n",methods[i]);
}
return 0;
}
编译(其中的-levent表示链接第三方的库):
root@iZm5e9phbzdxx0lysrv9t2Z:/home# ll
total 1092
drwxr-xr-x 3 root root 4096 Oct 25 21:23 ./
drwxr-xr-x 20 root root 4096 Oct 25 20:27 ../
-rw-r--r-- 1 root root 289 Oct 23 21:44 01_getmethods.c
drwxr-xr-x 12 1000 1000 4096 Oct 25 20:49 libevent-2.1.12-stable/
-rw-r--r-- 1 root root 1100847 Oct 23 21:40 libevent-2.1.12-stable.tar.gz
root@iZm5e9phbzdxx0lysrv9t2Z:/home# gcc 01_getmethods.c -l event
01_getmethods.c: In function ‘main’:
01_getmethods.c:7:23: warning: initialization of ‘char **’ from incompatible pointer type ‘const char **’ [-Wincompatible-pointer-types]
7 | char ** methods = event_get_supported_methods();//获取libevent后端支持的方法
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
root@iZm5e9phbzdxx0lysrv9t2Z:/home#
可以忽略该警告,代表编译完成。默认生成a.out执行文件。
执行:
root@iZm5e9phbzdxx0lysrv9t2Z:/home# ls
01_getmethods.c a.out libevent-2.1.12-stable libevent-2.1.12-stable.tar.gz
root@iZm5e9phbzdxx0lysrv9t2Z:/home# ./a.out
epoll
poll
select
root@iZm5e9phbzdxx0lysrv9t2Z:/home#
同时也能看到libevent在当前主机上后端支持的多路IO方法。
#include
#include
int main()
{
char ** methods = event_get_supported_methods();//获取libevent后端支持的方法
int i =0;
for(i = 0;methods[i] != NULL ;i++)
{
printf("%s\n",methods[i]);
}
struct event_base * base = event_base_new();
printf("\nlibevent在当前主机上后端支持的多路IO方法:%s\n",event_base_get_method(base));
return 0;
}
root@iZm5e9phbzdxx0lysrv9t2Z:/home# ls
01_getmethods.c a.out libevent-2.1.12-stable libevent-2.1.12-stable.tar.gz
root@iZm5e9phbzdxx0lysrv9t2Z:/home# ./a.out
epoll
poll
select
libevent在当前主机上后端支持的多路IO方法:epoll
root@iZm5e9phbzdxx0lysrv9t2Z:/home#
/*
This exmple program provides a trivial server program that listens for TCP
connections on port 9995. When they arrive, it writes a short message to
each client connection, and closes each connection once it is flushed.
Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
*/
#include
#include
#include
#include
#ifndef WIN32
#include
# ifdef _XOPEN_SOURCE_EXTENDED
# include
# endif
#include
#endif
#include
#include
#include
#include
#include
static const char MESSAGE[] = "Hello, World!\n";
static const int PORT = 9995;
static void conn_readcb(struct bufferevent *bev, void *user_data);
static void listener_cb(struct evconnlistener *, evutil_socket_t,
struct sockaddr *, int socklen, void *);
static void conn_writecb(struct bufferevent *, void *);
static void conn_eventcb(struct bufferevent *, short, void *);
static void signal_cb(evutil_socket_t, short, void *);
int
main(int argc, char **argv)
{
struct event_base *base;
struct evconnlistener *listener;
struct event *signal_event;
struct sockaddr_in sin;
#ifdef WIN32
WSADATA wsa_data;
WSAStartup(0x0201, &wsa_data);
#endif
base = event_base_new();//创建event_base根节点
if (!base) {
fprintf(stderr, "Could not initialize libevent!\n");
return 1;
}
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
//创建链接侦听器
listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
(struct sockaddr*)&sin,
sizeof(sin));
if (!listener) {
fprintf(stderr, "Could not create a listener!\n");
return 1;
}
//创建信触发的节点
signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);
//将信号节点上树
if (!signal_event || event_add(signal_event, NULL)<0) {
fprintf(stderr, "Could not create/add a signal event!\n");
return 1;
}
event_base_dispatch(base);//循环监听
evconnlistener_free(listener);//释放链接侦听器
event_free(signal_event);//释放信号节点
event_base_free(base);//释放event_base根节点
printf("done\n");
return 0;
}
static void
listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
struct sockaddr *sa, int socklen, void *user_data)
{
struct event_base *base = user_data;
struct bufferevent *bev;
//将fd上树
//新建一个buffervent节点
bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
if (!bev) {
fprintf(stderr, "Error constructing bufferevent!");
event_base_loopbreak(base);
return;
}
//设置回调
bufferevent_setcb(bev, conn_readcb, conn_writecb, conn_eventcb, NULL);
bufferevent_enable(bev, EV_WRITE | EV_READ);//设置写事件使能
//bufferevent_disable(bev, EV_READ);//设置读事件非使能
bufferevent_write(bev, MESSAGE, strlen(MESSAGE));//给cfd发送消息 helloworld
}
static void conn_readcb(struct bufferevent *bev, void *user_data)
{
char buf[1500]="";
int n = bufferevent_read(bev,buf,sizeof(buf));
printf("%s\n",buf);
bufferevent_write(bev, buf,n);//给cfd发送消息
}
static void
conn_writecb(struct bufferevent *bev, void *user_data)
{
struct evbuffer *output = bufferevent_get_output(bev);//获取缓冲区类型
if (evbuffer_get_length(output) == 0) {
// printf("flushed answer\n");
// bufferevent_free(bev);//释放节点 自动关闭
}
}
static void
conn_eventcb(struct bufferevent *bev, short events, void *user_data)
{
if (events & BEV_EVENT_EOF) {
printf("Connection closed.\n");
} else if (events & BEV_EVENT_ERROR) {
printf("Got an error on the connection: %s\n",
strerror(errno));/*XXX win32*/
}
/* None of the other events can happen here, since we haven't enabled
* timeouts */
bufferevent_free(bev);
}
static void
signal_cb(evutil_socket_t sig, short events, void *user_data)
{
struct event_base *base = user_data;
struct timeval delay = { 2, 0 };
printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");
event_base_loopexit(base, &delay);//退出循环监听
}
01libevent库的下载与安装并且测试是否安装成功_Mango酱的博客-CSDN博客_libevent下载
libssl-dev安装步骤_WangEason1985的博客-CSDN博客_windows安装libssl-dev
1 Libevent官方 · libevent深入浅出
linux安装 Libevent安装和使用_东山富哥的博客-CSDN博客_libevent安装
Libenent: configure: error: openssl is a must but can not be found._贪心的鬼的博客-CSDN博客
linux无法编译libevent,一直报错,但是我有装openssl - SegmentFault 思否
记录关于libevent安装错误:configure: error: openssl is a must but can not be found. You should add the direct_youngchanlll的博客-CSDN博客_安装libevent报错