epoll经典代码示例

1. epoll原理
原理性的知识不再另做说明,我在这里附上收藏整理的两篇经典文章:
2. epoll服务器端经典示例
2.1 逻辑框架

2.2 代码
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <pthread.h>
#define true 1
#define false 0
#define MAX_EVENT_NUMBER 1024
#define BUFFER_SIZE 10
/*将文件描述符设置为非阻塞*/
int setnonblocking(int fd)
{
int old_option = fcntl(fd, F_GETFL);
int new_option = old_option | O_NONBLOCK;
fcntl(fd, F_SETFL, new_option);
return old_option;
}
/*将文件描述符fd上的EPOLLIN注册到epollfd指示的epoll内核事件表中。 参数enable_et 指定是否对fd采用ET模式*/
void addfd(int epollfd, int fd, int enable_et)
{
struct epoll_event event;
event.data.fd = fd;
event.events = EPOLLIN;
if(enable_et){
event.events |= EPOLLET;
}
epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event );
setnonblocking(fd);
}
/*LT 模式的工作原理*/
void lt(struct epoll_event *events, int number, int epollfd, int listenfd)
{
char buf[BUFFER_SIZE];
int i = 0;
for(i= 0;i<number;i++){
int sockfd = events[i].data.fd;
if(sockfd == listenfd){
struct sockaddr_in client_address;
socklen_t client_addrlength = sizeof(client_address);
int connfd = accept(listenfd, (struct sockaddr *)&client_address, &client_addrlength);
addfd(epollfd, connfd, false);
}else if(events[i].events & EPOLLIN){
/*只要socket读缓存中的还有未读的数据,此代码就能触发*/
printf("event trigger once\n");
memset(buf, 0, BUFFER_SIZE);
int ret = recv(sockfd, buf, BUFFER_SIZE-1, 0);
if(ret <= 0){
close(sockfd);
continue;
}
printf("get %d bytes of content: %s\n", ret, buf);
}else{
printf("Something else happen !!!\n");
}
}
}
/*ET 模式的工作流程*/
void et(struct epoll_event* events, int number, int epollfd, int listenfd)
{
char buf[BUFFER_SIZE];
int i=0;
for(i =0; i<number; i++){
int sockfd = events[i].data.fd;
if(sockfd == listenfd){
struct sockaddr_in client_address;
socklen_t client_addrlength = sizeof(client_address);
int connfd = accept(listenfd, (struct sockaddr* )&client_address, &client_addrlength);
addfd(epollfd, connfd, true);/*对connfd开启ET模式*/
}else if(events[i].events & EPOLLIN){
/*这段代码不会被重复触发,所以我们循环读取数据,以确保把socket缓冲区的数据全部读取*/
printf("Event trigger once !!!\n");
while(1){
memset(buf, 0, BUFFER_SIZE);
int ret = recv(sockfd, buf, BUFFER_SIZE-1, 0);
if(ret < 0){
/*对于非阻塞IO,下面的事件成立标识数据已经全部读取完毕。此后,epoll就能再次触发sockfd上的sockfd的EPOLLIN事件,以驱动下一次读操作*/
if((errno == EAGAIN) || (errno == EWOULDBLOCK)){
printf("read later\n");
break;
}
close(sockfd);
break;
}else if(ret == 0){
close(sockfd);
}else{
printf("get %d bytes of content: %s\n", ret, buf);
}
}
}else{
printf("something else happen\n");
}
}
}
int main(int argc, char *argv[])
{
if(argc <= 2){
printf("Usage: %s ip_address port_number\n", argv[0]);
return 1;
}
const char *ip = argv[1];
int port = atoi(argv[2]);
int ret = 0;
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
inet_pton(AF_INET, ip, &address.sin_addr);
address.sin_port = htons(port);
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
assert(listenfd >= 0);
ret = bind(listenfd, (struct sockaddr *)&address, sizeof(address));
assert(ret != -1);
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
ret = listen(listenfd, 5);
assert(ret != -1);
struct epoll_event events[MAX_EVENT_NUMBER];
int epollfd = epoll_create(5);
assert(epollfd != -1);
addfd(epollfd, listenfd, true);
while(1){
int ret = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);
if(ret<0){
printf("epoll failure\n");
break;
}
//lt(events, ret, epollfd, listenfd);
et(events, ret, epollfd, listenfd);
}
close(listenfd);
return 0;
}
epoll经典代码示例的更多相关文章
- Python实现各种排序算法的代码示例总结
Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示 ...
- 使用XStream注解实现Java对象与XML互相转换的代码示例
本文记录一下使用xstream这个api的注解特性对Java对象与XML字符串相互转换的一些代码示例. 我们很多人都处理过XML文件,也有很多非常成熟的第三方开源软件.如:jdom.dom4j等 ...
- 高级渲染技巧和代码示例 GPU Pro 7
下载代码示例 移动设备正呈现着像素越来越高,屏幕尺寸越来越小的发展趋势. 由于像素着色的能耗非常大,因此 DPI 的增加以及移动设备固有的功耗受限环境为降低像素着色成本带来了巨大的压力. MSAA 有 ...
- Java8-Function使用及Groovy闭包的代码示例
导航 定位 概述 代码示例 Java-Function Groovy闭包 定位 本文适用于想要了解Java8 Function接口编程及闭包表达式的筒鞋. 概述 在实际开发中,常常遇到使用模板模式的场 ...
- [IOS 开发] 懒加载 (延迟加载) 的基本方式,好处,代码示例
懒加载的好处: 1> 不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强 2> 每个属性的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强,松耦合 ...
- SELECT控件操作的JS代码示例
SELECT控件操作的JS代码示例 1 检测是否有选中 if(objSelect.selectedIndex > -1) { //说明选中 } else { //说明没有选中 } 2.动态创建s ...
- 转:HIBERNATE一些_方法_@注解_代码示例---写的非常好
HIBERNATE一些_方法_@注解_代码示例操作数据库7步骤 : 1 创建一个SessionFactory对象 2 创建Session对象 3 开启事务Transaction : hibernate ...
- C#与数据库访问技术总结(十五)之 DataAdapter对象代码示例
DataAdapter对象代码示例 下面的代码将说明如何利用DataAdapter对象填充DataSet对象. private static string strConnect=" data ...
- C#与数据库访问技术总结(六)之Command对象创建SQl语句代码示例
Command对象创建SQl语句代码示例 说明:前面介绍了 Command 对象的方法和一些属性,回顾一下 Command对象主要用来执行SQL语句.利用Command对象,可以查询数据和修改数据. ...
随机推荐
- 对HashMap的一次记录
HashMap的具体学习,认识了解. 前言 也是最近开始面试才发现,HashMap是问的真多.以前听学长或自己在网上看到过一些面试资料都在说集合.线程这块比较重要,面试的重点.自己也是有那抵触情绪,所 ...
- 数据结构与算法 java描述 第一章 算法及其复杂度
目录 数据结构与算法 java描述 笔记 第一章 算法及其复杂度 算法的定义 算法性能的分析与评价 问题规模.运行时间及时间复杂度 渐进复杂度 大 O 记号 大Ω记号 Θ记号 空间复杂度 算法复杂度及 ...
- 三年Android开发快手、美团、支付宝连挂,怒刷1549页面试题字节上岸
刚开始面试的时候我真的是处处碰壁,面一家挂一家,面完之后怀疑自我,是不是自己真的太菜了找不到工作.工作本身就是双向选择,一家不行再换一家,总有合适的,千万不要因为别人的一句话就全盘否定自己,一定要自信 ...
- 更改控制节点IP后更改openstack配置
by lt 1.修改openstack配置 sed -i "s/原有IP/更新后IP/g" `grep 原有ip -rl /etc` 2.修改南大苏富特云系统其他组件配置 sed ...
- RocketMQ原理分析&场景问题
硬核干货分享,欢迎关注[Java补习课]成长的路上,我们一起前行 ! <高可用系列文章> 已收录在专栏,欢迎关注! 一.RocketMQ的基本原理 RocketMQ基本架构图如下 从这个架 ...
- repeatedly function in Clojure
user=> (doc repeatedly) clojure.core/repeatedly ([f] [n f]) Takes a function of no args, presumab ...
- MySQL学习01(初识MySQL)
初识MySQL 只会写代码的是码农:学好数据库,基本能混口饭吃:在此基础上再学好操作系统和计算机网络,就能当一个不错的程序员.如果能再把离散数学.数字电路.体系结构.数据结构/算法.编译原理学通透,再 ...
- PTA数据结构习题集
https://blog.csdn.net/qq_43733499/category_8956159.html https://www.cnblogs.com/nonlinearthink/tag/% ...
- CVE-2020-0796提权操作
简介 最新的windows10中使用了SMBv3协议,SMBv3协议在压缩消息时,未对头部数据做任何检查,导致恶意攻击者可以直接使用,从而导致内存破坏漏洞. 该漏洞可远程进行攻击目标系统,但目前只做到 ...
- 流动的观察者模式 | Flutter 设计模式
观察者模式,又称发布订阅模式,是一种行为设计模式--你可以定义一种订阅机制,可在对象事件发生时通知多个 观察 该对象的其他对象. 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主 ...