高并发网络服务器-多路IO - epoll

多路IO - epoll

将检测文件描述符的变化委托给内核去处理,然后内核将发生变化的文件描述符对应的事件返回给应用程序。

更多技术文档参见:https://github.com/IsConor/C_and_C_plus.git

函数介绍

Int epoll_create( int size );

函数说明:创建一个树根

参数说明

Size:最大节点数,此参数在Linux2.6.8已被忽略,但必须传递一个大于0的数

返回值

成功:返回一个大于0的文件描述符,代表整个树的树根。

失败:返回-1,并设置errno值。

函数介绍

Int epoll_ctl( int epfd,  int op,  int fd,  struct epoll_event * event );

函数说明:将要监听的节点在epoll树上添加,删除和修改

参数说明

epfd: epoll树根

op:

EPOLL_CTL_ADD: 添加事件节点到树上

EPOLL_CTL_DEL: 从树上删除事件节点

EPOLL_CTL_MOD: 修改树上对应的事件节点

fd:事件节点对应的文件描述符

event:要操作的事件节点

typedef union epoll_data{

void      *ptr;

int        fd;

uint32_t   u32;

uint64_t   u64;

} epoll_data_t;

struct epoll_event {

uint32_t   events;

epoll_data_t data;

};

event.events常用的有:

EPOLLIN: 读事件

EPOLLOUT:写事件

EPOLLERR:错误事件

EPOLLET:边缘触发模式

Event.data.fd: 要监控的事件对应的文件描述符

函数介绍

Int epoll_wait( int epfd,  struct epoll_event * events,  int maxevents,  int timeout );

函数说明:委托内核监控epoll树的事件节点

函数参数

Epfd: epoll树根

Events: 传出参数,结构体数组

Maxevents:events数组大小

Timeout:

-1:一直阻塞

0:表示不阻塞

>0:表示超时的时长

使用epoll模型开发服务器流程:

1 设置socket,得到文件描述符lfd

2 设置端口复用 --- setsockopt()

3 绑定 --- bind()

4 监听 ---- listen()

5 创建一颗epoll树

Int epfd = epoll_create();

//将监听描述符上树

struct epoll_event ev;

ev.events = EPOLLIN;

ev.data.fd = lfd;

epoll_ctl( epfd,  EPOLL_CTL_ADD,  lfd,  &ev );

Struct epoll_event events[1024];

While(1)

{

Nready = epoll_wait( epfd,  events,  1024,  -1 );

If( nready < 0 )

{

If( errno == EINTR )

{

Continue;

}

Break;

}

For( i=0; i<nready; i++ )

{

Sockfd = events[i].data.fd;

//有客户端连接请求到来

If( sockfd == lfd )

{

cfd = accept( lfd, NULL, NULL );

//将cfd对应的读事件上epoll树

ev.data.fd = cfd;

ev.events = EPOLLIN;

epoll_ctl( epfd,  EPOLL_CTL_ADD,  cfd,  &ev );

continue;

}

//有客户端发送数据过来

N = read( sockfd,  buf,  sizeof(buf) );

If(n <= 0)

{

Close(sockfd);

//将sockfd对应的事件节点从epoll树上删除

Epoll_ctl( epfd,  EPOLL_CTL_DEL,  sockfd,  NULL );

Printf(“read error or client close\n”);

Continue;

}

Else

{

Write( sockfd,  buf,  n );

}

}

}

Close ( lfd );

Return 0;

进阶epoll

epoll的两种工作模式

epoll有两种工作模式 ET 和 LT 模式

水平触发:高电平代表1

只要缓冲区中有数据,就一直通知

边缘触发:电平有变化就代表1

缓冲区中有数据只会通知一次,之后再有数据才会通知

1 Epoll默认情况下是LT模式,在这种模式下,若读数据一次性没有读完,缓冲区内还有可读数据,则epoll_wait还会再次通知

2 若将epoll设置为ET模式,若读数据的时候一次性没有读完,则epoll_wait不再通知,直到下次有新的数据发来

Epoll的ET模式的非阻塞模式:

在ET模式下,如何在epoll_wait返回一次的情况下读完数据?

循环读数据,直到读完数据,但是读完数据后会阻塞

若能一次性读完,还需要设置什么?

将通信文件描述符设置为非阻塞

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IsConor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值