0
点赞
收藏
分享

微信扫一扫

libevent

libevent概述

Libevent 是开源社区的一款高性能的 I/O 框架库,使用 Libevent 的著名案例有:高性能的分布式内存对象缓存软件 memcached,Google 浏览器 Chromium 的 Linux 版本。作为一个 I/O 框架库,Libevent 具有如下特点:

◼ 跨平台支持。 Libevent 支持 Linux、Unix 和 Windows。

◼ 统一事件源。Libevent 对 I/O 事件、信号和定时事件提供统一的处理。

◼ 线程安全。Libevent 使用 libevent_pthreads 库来提供线程安全支持。

◼ 基于 Reactor 模式的实现。

使用示例
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <event.h>
#include <signal.h>

void signal_cb(int fd, short event, void *arg)
{
	printf("%d Signal triggered\n");
}

void timeout_cb(int fd, short event, void *arg)
{
	printf("timeout\n");
}

int main()
{
	struct event_base *base = event_init();

	struct event *signal_event = evsignal_new(base, SIGINT, signal_cb,NULL);
	event_add(signal_event, NULL);

	struct timeval tv = { 2, 0 };
	struct event *timeout_event = evtimer_new(base, timeout_cb, NULL);
	event_add(timeout_event, &tv);

	event_base_dispatch(base);

	event_free(signal_event);
	event_free(timeout_event);
	event_base_free(base);

	exit(0);
}

/*
	define evsignal_new(b, x, cb, arg) \
	event_new((b), (x), EV_SIGNAL | EV_PERSIST, (cb), (arg))

	#define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))

	struct event *event_new(struct event_base *base, evutil_socket_t fd,
	short events, void (*cb)(evutil_socket_t, short, void*), void *arg);
*/
libevent支持事件类型
#define EV_TIMEOUT0x01/* 定时事件 */
#define EV_READ0x02/* 可读事件 */
#define EV_WRITE0x04/* 可写事件 */
#define EV_SIGNAL0x08/* 信号事件 */
#define EV_PERSIST0x10/* 永久事件 */

/* 边沿触发事件,需要 I/O 复用系统调用支持,比如 epoll */ #define EV_ET 0x20

服务器端:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <event.h>

#define MAX_CLIENT 100
#define DATALENGTH 1024

struct event_base *base = NULL;

typedef struct ClientData
{
	int fd;
	struct event *ev;
}ClientData;

void InitClients(ClientData clients[])
{
	int i = 0;
	for (; i < MAX_CLIENT; ++i)
	{
		clients[i].fd = -1;
		clients[i].ev = NULL;
	}
}

void InsertToClients(ClientData clients[], int fd, struct event *ev)
{
	int i = 0;
	for (; i < MAX_CLIENT; ++i)
	{
		if (clients[i].fd == -1)
		{
			clients[i].fd = fd;
			clients[i].ev = ev;
			break;
		}
	}
}

struct event * DeleteOfClients(ClientData clients[], int fd)
{
	int i = 0;
	for (; i < MAX_CLIENT; ++i)
	{
		if (clients[i].fd == fd)
		{
			clients[i].fd = -1;
			return clients[i].ev;
		}
	}
	return NULL;
}

//初始化 socket
int InitSocket()
{
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1) return -1;

	struct sockaddr_in saddr;
	memset(&saddr, 0, sizeof(saddr));
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(6000);
	saddr.sin_addr.s_addr = inet_addr("127.0.0.1");

	int res = bind(sockfd, (struct sockaddr*)&saddr, sizeof(saddr));
	if (res == -1) return -1;

	res = listen(sockfd, 5);
	if (res == -1) return -1;

	return sockfd;
}

void client_fun(int fd, short event, void *arg)
{
	ClientData *clients = (ClientData*)arg;

	char buff[DATALENGTH] = { 0 };
	int n = recv(fd, buff, DATALENGTH - 1, 0);
	if (n <= 0)
	{
		struct event *ev = DeleteOfClients(clients, fd);
		event_free(ev);
		printf("A Client Disconnect\n");
		return;
	}

	printf("%d:%s\n", fd, buff);
	send(fd, "OK", 2, 0);
}

void sockfd_fun(int fd, short event, void *arg)
{
	ClientData *clients = (ClientData*)arg;
	struct sockaddr_in caddr;
	socklen_t len = sizeof(caddr);
	int c = accept(fd, (struct sockaddr*)&caddr, &len);
	if (c < 0)
	{
		return;
	}

	struct event *ev = event_new(base, c, EV_READ | EV_PERSIST, client_fu n, arg);
	InsertToClients(clients, c, ev);
	event_add(ev, NULL);
	printf("A client Link\n");
}

int main()
{
	int sockfd = InitSocket();
	assert(sockfd != -1);

	ClientData clients[MAX_CLIENT];
	InitClients(clients);

	base = event_init();

	struct event *ev = event_new(base, sockfd, EV_READ | EV_PERSIST, soc kfd_fun, (void*)clients);
	event_add(ev, NULL);

	event_base_dispatch(base);
	event_free(ev);
	event_base_free(base);

	exit(0);
}
举报

相关推荐

0 条评论