多路复用并发模型  -- epoll

监控事件 events

EPOLLIN                  fd可读

EPOLLOUT              fd可写

EPOLLPRI                fd紧急数据可读

EPOLLERR              fd发生错误

EPOLLHUP              fd 被挂起

EPOLLONESHOT    fd 只监控 1 次,监控完后自动删除

EPOLLLT                 epoll 工作模式,设置为 水平触发模式

EPOLLET                 epoll 工作模式,设置为 边缘触发模式

多路复用并发模型  -- epoll

epoll 工作模式

1)水平触发模式 (Level Triggered, 默认值)

  事件发生时,应用程序可以不立即处理。

  没有做处理,则下次epoll_wait 事件仍然被置位

2)边缘触发模式 (Edge Triggered)

  事件发生时,应用程序必须处理

  否则,这个事件会被丢弃

epoll工作在ET模式的时候,必须使用非阻塞套接口,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死

水平触发模式和边缘触发模式

  水平触发监控的是状态:   有没有消息可读

  边缘触发监控的是变换: 是不是由可读变成不可读,或者由不可读变成可读

#include<stdio.h>
#include<unistd.h>
#include<string.h> #include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h> #include <map> #include<sys/epoll.h>
#include<sys/time.h> #define SRV_PORT 0xabcd
#define DEAL_NUM 2
#define CONN_MAX 10000 int fd;
int nConn = 0;//num of connection
std::map<int, struct socket_in> g_fdmap; void epoll_process(int epfd,struct epoll_events,int cnt)
{
int i, iRet = 0;;
int newfd;
char szBuff[1000];
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
struct epoll_event ect; std::map<int struct socket_in>::iterator it; for (i = 0; i < cnt; ++i)
{
//Accept the message and process it
if (evts[i].data.fd == STDIN_FILENO)
{ }
//new client to connet
else if (evts[i].data.fd == fd)
{
newfd = accept(fd, (struct sockaddr*)&addr, &addrlen);
if (newfd < 0)
{
perror("Fail to accept!");
continue;;
}
if (nConn == CONN_MAX)
{
write(newfd, "Over limit!", 12);
printf("Over connect..\n");
close(newfd);
continue;
}
//normal operation
g_fdmap.insert(std::make_pair(newfd, addr)); //add newfd to epfd for monitor
evt.events = EPOLLIN;
evt.data.fd = newfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, newfd, &evt); //reponse client
write(newfd, "Welcome", 8); printf("\rNew Connect from %s[%d]\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); }
//recviver client message
else
{
memset(szBuff, 0, 1000); it = g_fdmap.find(evts[i].data.fd);
if (it == g_fdmap.end())
{
printf("\rUnknow client fd: %d\n", evts[i].data.fd);
continue;
} iRet=read(evts.data.fd, szBuff, 1000);
if (iRet < 0)
{
perror("Fail to read!");
continue;
}
else if (iRet == 0)
{
printf("Disconnct from %s[%d]\n", inet_ntoa((it->second()).sin_addr),
ntohs((it->second()).addr.sin_port)); //delete fd from epfd monitor
epoll_ctl(epfd, EPOLL_CTL_DEL,evts[i].data.fd,evts+i); //erase fa from map
g_fdmap.erase(it);
}
//normal operation
else
{
printf("\rRecv from %s[%d]:%s\n", inet_ntoa((it->second()).sin_addr,
ntohs((it->second()).addr.sin_port), szBuff);
} }
} return;
} void StarEpoll()
{
int iRet;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr); fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
perror("Fail to socket!");
return;
} addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(SRV_PORT); iRet = bind(fd, (struct sockaddr*)&addr, addrlen);
if (iRet)
{
perror("Fail to bind!");
close(fd);
return;
} iRet = listen(fd, 100);
if (iRet)
{
perror("Fail to listen!");
close(fd);
return;
} ///////////////init epollfd int epfd = epoll_create(1);
if (epfd < 0)
{
perror("Fail to epoll_create!");
close(fd);
return;
} struct epoll_event evt; //add stdin
evt.events = EPOLLIN;
evt.data.fd =STDIN_FILENO;
epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO); //add tcp server fd
evt.events = EPOLLIN;
evt.data.fd = fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, &evt); /////////////////////// struct epoll_event evts[DEAL_NUM]; int cnt;
while (1)
{
cnt = epoll_wait(epfd, evts, DEAL_NUM, -1);
if (cnt < 0)
{
perror("Fail to epoll_wait!");
break;
}
else if (cnt == 0)
{
//timeout
continue;
}
else
{
epoll_process(epfd, evts, cnt);
}
} close(fd);
return;
} int main()
{
StarEpoll(); return 0;
}

  

33网络通信之Epoll模型的更多相关文章

  1. Epoll模型详解

    Linux 2.6内核中提高网络I/O性能的新方法-epoll I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数. 1.为什么select落后    首先,在Lin ...

  2. 转一篇关于epoll模型的博文

    以前就看过这篇关于epoll文章,现在又翻出来看了一下,很久不看的知识真是容易忘啊. 原文出处: http://blog.163.com/huchengsz@126/blog/static/73483 ...

  3. 【转】select和epoll模型的差异

    http://www.cppblog.com/converse/archive/2008/10/12/63836.html epoll为什么这么快 epoll是多路复用IO(I/O Multiplex ...

  4. linux epoll模型

    原文:http://yjtjh.blog.51cto.com/1060831/294119 Linux I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数.Linux ...

  5. Linux网络服务器epoll模型的socket通讯的实现(一)

    准备写一个网络游戏的服务器的通讯模块,参考网上看到的一些代码,在linux下面实现一个多线程的epoll模型的socket通讯的代码,以下是第一部分多线程的切换代码: 1 #include <s ...

  6. (OK) Linux epoll模型—socket epoll server client chat

    http://www.cnblogs.com/venow/archive/2012/11/30/2790031.html http://blog.csdn.net/denkensk/article/d ...

  7. nginx中的epoll模型

    要了解epoll模型,就要一个一个知识点由浅至深地去探索. 1.IO复用技术 IO流请求操作系统内核,有串行处理和并行处理两种概念. 串行处理是前面一个操作处理地时候,后面的所有操作都需要等待.因此, ...

  8. select 和epoll模型区别

    1.select 和epoll模型区别 1.1.网络IO模型概述 通常来说,网络IO可以抽象成用户态和内核态之间的数据交换.一次网络数据读取操作(read),可以拆分成两个步骤:1)网卡驱动等待数据准 ...

  9. Epoll模型

    Epoll模型 相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率.因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多.并且,在l ...

随机推荐

  1. 网易云课堂-spark

    ==============================Flink比spark优秀,但既生瑜何生亮,所以Flink没火起来 为了使用sortbykey,需要RDD的元素是key-value的形式 ...

  2. git知识点

    先说几个名词 未被追踪的文件:指的是新建的文件或文件夹且还没加入到暂存区(新建的还没有被git add 过得) 未加入到暂存区的文件:指的是已经被追踪过,但是没有加入到暂存区(已经执行过git add ...

  3. 《HTTP - http首部信息》

    推荐一首歌 - 僕が死のうと思ったのは (曾经我也想过一了百了) 也就听了几十遍而已 经历一番波折,终于正式到了北京. 刚开始是很艰难的,多走两步就好了,不是么. 1:首部字段 Cache-Contr ...

  4. Appium入门(4)__ Appium Client安装

    打算使用 Python 语言编写 appium 自动化测试脚本 一.前提: 1.安装Python语言 到Python官网下载最新版本:https://www.python.org/ 2.安装Pytho ...

  5. tensorflow入门笔记(五) name_scope和variable_scope

    一.上下文管理器(context manager) 上下文管理器是实现了上下文协议的对象,主要用于资源的获取与释放.上下文协议包括__enter__.__exit__,简单说就是,具备__enter_ ...

  6. python摸爬滚打之day07----基本数据类型补充, 集合, 深浅拷贝

    1.补充 1.1  join()字符串拼接. strs = "阿妹哦你是我的丫个哩个啷" nw_strs = "_".join(strs) print(nw_s ...

  7. 【PyQt5-Qt Designer】猜数字(小项目)

    参考:https://zhuanlan.zhihu.com/p/28287825 https://www.cnblogs.com/hhh5460/p/5174266.html 最终效果: 本次练习涉及 ...

  8. Postfix 邮件服务器搭建

    搭建服务环境: Centos 6 配置域名hosts: mail.demonC6.com 1.清理系统自带的邮件软件 # rpm -qa | grep sendmail* # rpm -e sendm ...

  9. vuex是什么?怎么使用?哪种功能场景使用它?

    vuex是vue框架中状态管理.在main.js引入store,注入.新建了一个目录store,...export.应用场景有:单页应用中,组件之间的状态.应用实例:音乐播放.登录状态.加入购物车等等

  10. SQL Server的等待事件

    具体查看: https://www.sqlshack.com/sql-server-wait-types/ 早上10:00, 公司的订单数据更新缓慢,查看了监控的sql信息,有大量的HADR_SYNC ...