博客
关于我
libevent在windows下使用步骤详解
阅读量:792 次
发布时间:2023-01-31

本文共 4376 字,大约阅读时间需要 14 分钟。

Libevent网络库入门及在Windows环境下的编译与使用

Libevent 简介

Libevent 是一个用 C 语言编写的、轻量级、高性能的开源网络库,广泛应用于网络服务器、客户端和其他网络相关的开发。它基于事件驱动模型,支持多种 I/O 多路复用技术,包括 epoll、poll、select 和 kqueue 等,适用于高并发网络场景。相比ACE,Libevent 的代码更简洁、易读,支持跨平台,适用于 Windows、Linux、*BSD 和 Mac OS 等操作系统。

本文将详细介绍如何在 Windows 环境下编译和使用 Libevent,提供完整的hands-on 实验过程。

一、环境准备

  • 操作系统:Win8.1
  • 开发工具:Visual Studio 2008
  • 下载地址http://libevent.org/
  • Libevent 版本:2.0.22-stable

二、编译静态库

1. 解压源码

将下载的 tar.gz 文件解压,得到 libevent-2.0.22-stable 文件夹。

2. 添加宏定义

libevent-2.0.22-stable 文件夹中,找到以下文件并在开头添加宏定义 #define _WIN32_WINNT 0x0500

  • event_iocp.c
  • evthread_win32.c
  • listener.c

3. 编译

使用 Visual Studio 的命令行工具(nmake),从项目根目录执行以下命令:

nmake /f Makefile.nmake

这将生成三个静态库:

  • libevent_core.lib
  • libevent_extras.lib
  • libevent.lib

三、项目配置

1. 文件夹结构

  • 在项目目录下创建 libevent 文件夹。
  • libevent 中创建 libinclude 文件夹,将编译生成的三个库和相关头文件复制到 lib 文件夹中。
  • libevent-2.0.22-stable\include 文件夹下的所有内容复制到 include 文件夹。

2. Visual Studio 配置

  • VC++ 目录:将 libinclude 文件夹添加到库和包含目录中。
  • C/C++ 成本:在运行库标志中选择 /MT(Release)或 /MTd(Debug)。
  • 链接器:输入依赖项中添加 ws2_32.libwsock32.lib、以及生成的三个 Libevent 库。

四、编写示例程序

1. simple personalities.Connection

#include 
#include
#include
#include
#define MSG "Hello, World!\n"#define PORT 9995static void write handler(struct bufferevent * bev, void * user_data) { struct evbuffer * output = bufferevent_get_output(bev); if (evbuffer_get_length(output) == 0) { printf("flushed\n"); bufferevent_free(bev); }}static void connection handler(struct bufferevent * bev, short events, void * user_data) { if (events & BEV_EVENT_EOF) { printf("Connection closed\n"); } else if (events & BEV_EVENT_ERROR) { printf("Error on connection: %s\n", strerror(errno)); } bufferevent_free(bev);}static void signal handler(int sig) { static struct event_base * base = (struct event_base *) user_data; struct timeval delay = {2, 0}; printf("Caught signal\n"); event_base_loopexit(base, &delay);}static void listener handler(struct evconnlistener * listener, int fd, struct sockaddr * sa, void * user_data) { struct event_base * base = (struct event_base *) user_data; struct bufferevent * bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); if (!bev) { fprintf(stderr, "Error creating bufferevent\n"); return; } bufferevent_setcb(bev, write handler, connection handler, NULL); bufferevent_enable(bev, EV_WRITE); bufferevent_write(bev, MSG, strlen(MSG));}int main(int argc, char ** argv) { struct event_base * base = event_base_new(); if (!base) { return 1; } struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(PORT); struct evconnlistener * listener = evconnlistener_new_bind(base, listener handler, base, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1, (struct sockaddr *)&sin, sizeof(sin)); if (!listener) { return 1; } signal(SIGINT, signal handler); event_base_dispatch(base); evconnlistener_free(listener); event_base_free(base); printf("Done\n"); return 0;}

2. HTTP 服务器示例

#include 
#include
#include
static bool startHttpServer(const char * ip, int port, void (* cb)(struct evhttp_request *, void *), void * arg) { struct event_base * base = event_base_new(); struct evhttp * http = evhttp_new(base); if (!http) { return false; } int ret = evhttp_bind_socket(http, ip, port); if (ret != 0) { return false; } evhttp_set_gencb(http, cb, arg); event_base_dispatch(base); evhttp_free(http); return true;}void MyHttpServerHandler(struct evhttp_request * req, void * arg) { struct evbuffer * buf = evbuffer_new(); evbuffer_add_printf(buf, "Hello, world"); evhttp_send_reply(req, HTTP_OK, "Response", buf); evbuffer_free(buf);}int main() { WSADATA wsaData; WSAStartup(SOCKET_VERSION_ANY, &wsaData); startHttpServer("127.0.0.1", 8080, MyHttpServerHandler, NULL); WSACleanup(); return 0;}

五、常见错误处理

1. C2440 错误

在使用 Libevent 时,可能会遇到以下错误:

C: "void *" 到 "event_base *" 的初始化:无法从 "void *" 转换为 "event_base *"

这通常是由于 event_base * 的初始化没有正确传递用户数据。可以通过在定义 event_base * 时强制转换来解决。

2. socket通信依赖

确保已加载 Ws2_32.libwsock32.lib,这对于 Windows 执行网络通信是必不可少的。

六、总结

通过以上步骤,可以在 Windows 环境下成功编译并使用 Libevent 进行网络通信开发。Libevent 提供了便捷的事件驱动 API,使得开发高性能网络服务器变得更加简单。通过上述示例,可以快速开始项目开发,并根据具体需求进行扩展和优化。

转载地址:http://tggyk.baihongyu.com/

你可能感兴趣的文章
Kubernetes学习总结(12)—— 学习 kubernetes 的10个技巧或建议
查看>>
Kubernetes学习总结(13)—— Kubernetes 各个组件的概念
查看>>
Kubernetes学习总结(14)—— Kubernetes 实用命令总结
查看>>
Kubernetes学习总结(15)—— Kubernetes 实战之部署 Mysql 集群
查看>>
Kubernetes学习总结(16)—— Kubernetes 实战之部署 Redis 集群
查看>>
Kubernetes学习总结(17)—— Kubernetes 快速入门需要掌握的知识点总结
查看>>
Kubernetes学习总结(18)—— Kubernetes 容器网络
查看>>
Kubernetes学习总结(1)——Kubernetes入门简介
查看>>
Kubernetes学习总结(2)——Kubernetes设计架构
查看>>
Kubernetes学习总结(4)——Kubernetes v1.20 重磅发布 | 新版本核心主题 & 主要变化解读
查看>>
Kubernetes学习总结(5)——Kubernetes 常见面试题汇总
查看>>
Kubernetes学习总结(7)——学习 Kubernetes 的 Pod
查看>>
Kubernetes学习总结(9)—— 基础架构的未来是 K8s,那么 K8s 的未来在何方?
查看>>
kubernetes实战(十三):k8s使用helm持久化部署harbor集成openLDAP登录
查看>>
Kubernetes实战(一)-Kubernetes集群搭建
查看>>
Kubernetes实战(七)-优先级调度(Pod Priority Preemption)
查看>>
Kubernetes实战(三十一)-Calico网络部署(推荐)
查看>>
Kubernetes实战(三十三)-外部Etcd集群部署与调优(更安全的数据存储策略)
查看>>
Kubernetes实战(三十二)-Kubeadm 安装 Kubernetes v1.24.0
查看>>
Kubernetes实战(二十九)-集群资源管理(CPU & Memory)
查看>>