libevent——epoll 反应堆模型

本文介绍了libevent中的epoll服务器模型,详细阐述了如何利用epoll监听文件描述符的读写事件,包括如何处理滑动窗口机制导致的不能立即回写数据问题,以及如何使用结构体指针传递更丰富的信息。通过对fd的读写事件的智能管理,实现高效的数据传输和服务器响应。
摘要由CSDN通过智能技术生成

一、epoll服务器 :

epoll — 服务器 — 监听 — fd ----可读 ---- epoll返回 ---- read — 小写转大写 — write ---- epoll继续监听。

epoll 反应堆模型:

创建efd(epoll_create) ---- 增加fd(epoll_ctl) ---- epoll_wait返回----fd可读 ---- read ---- fd从树上摘下 ---- 设置监听fd写事件, 操作senddata ---- 小写转大写(或者直接回射) ---- 等待epoll_wait 返回 ---- 回写给客户端 ----efd从树上摘下 ---- 设置监听cfd读事件, 操作recvdata----epoll继续监听

1.增加了判断fd是否可以写,由于滑动窗口机制可以会造成服务器此刻不能通过fd向客户端回写数据。
2.evt[i].events = EPOLLIN;evt[I].data.fd不简单的传递fd了,而是传递一个指针(结构体指针)*ptr
	1 /*
	2  *epoll基于非阻塞I/O事件驱动
	3  */
	#include <stdio.h>
	#include <sys/socket.h>
	#include <sys/epoll.h>
	#include <arpa/inet.h>
	#include <fcntl.h>
	#include <unistd.h>
	#include <errno.h>
	#include <string.h>
	#include <stdlib.h>
	#include <time.h>

	#define MAX_EVENTS  1024                                    //红黑树所能监听的上限数
	#define BUFLEN 4096
	#define SERV_PORT   8080

	void recvdata(int fd, int events, void *arg);
	void senddata(int fd, int events, void *arg);

/* 描述就绪文件描述符相关信息 */

struct myevent_s {
   
	int fd;                                                 //要监听的文件描述符
	int events;                                             //对应的监听事件
	void *arg;                                              //泛型参数
	void(*call_back)(int fd, int events, void *arg);       //回调函数
	int status;                                             //是否在监听:1->在红黑树上(监听), 0->不在(不监听)
	char buf[BUFLEN];
	int len;
	long last_active;                                       //记录每次加入红黑树 g_efd 的时间值(若长时间不发数据,则踢掉),eventset和add会重置此时间	
};

int g_efd;                                                  //全局变量, 保存epoll_create返回的文件描述符
struct myevent_s g_events[MAX_EVENTS + 1];                  //自定义结构体类型数组. +1-->listen fd


/*将结构体 myevent_s 成员变量 初始化*/
//回调函数call_back的参数arg就是结构体myevent_s本身
void eventset(struct myevent_s *ev, int fd, void(*call_back)(int, int, void *), void *arg)
{
   
		ev->fd = fd;
		ev->call_back = call_back;
		ev->events = 0;
		ev->arg = arg;
		ev->status = 0;
		memset(ev->buf, 0, sizeof(ev->buf));
		ev->len = 0;
		ev->last_active = time(NULL);                       //调用eventset函数的时间(一旦调用就会改变),若长时间没改变(没收数据),就会被删除
	
		return;
}

/* 向 epoll监听的红黑树 添加一个 文件描述符 */

void eventadd(int efd, int events, struct myevent_s *ev)
{
   
	struct epoll_event epv = {
    0, {
    0 } };
	int op;
	epv.data.ptr 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值