socket epoll模型
linux 使用epoll主要目的是啥 为了实现非阻塞么?
socket本来就有阻塞和非阻塞两种模式,与epoll无关。
epoll是针对多socket操作(从select升级到poll再到epoll都是解决这个目的)。
如果不用poll方法,在阻塞模式下,操作多socket,要么用多线程,要么用多进程,都会带来一定的开发复杂度和性能降低。在非阻塞模式下,就要使用轮询,浪费处理能力很厉害。
所以,epoll是为了让程序只在一个线程中就能操作大量socket而提供的一个核心功能,同时还提供了很高的处理性能。
socket select、epoll模型本身是为了解决多客户端连接的问题。
同时,epoll由于机制的设置,在一点程度上降低了资源的使用,提高了效率。
一个进程内,select能打开的fd是有限制的,由宏FD_SETSIZE设置。默认值是1024。在某些时候,这个数值是远远不够用的。
解决的方法有两种,一是改动宏然后又一次编译内核,但与此同一时候会引起网络效率的下降;二是使用多进程来解决,可是创建多个进程是有代价的,并且进程间数据同步没有多线程间方便。
而epoll没有这个限制,它所支持的最大FD上限远远大于1024,在1GB内存的机器上是10万左右(详细数目能够cat/proc/sys/fs/file-max查看);
select函数每次都当监听的套接组有事件产生时就会返回。但却不能将有事件产生的套接字筛选出来。而是改变其在套接组的标志量,所以每次监听到事件,都须要将套接组整个遍历一遍。时间复杂度是O(n)。当FD数目添加时。效率会线性下降。
而epoll,每次会将监听套结字中产生事件的套接字加到一列表中,然后我们能够直接对此列表进行操作,而没有产生事件的套接字会被过滤掉,极大的提高了IO效率。
这一点尤其在套接字监听数量巨大而活跃数量非常少的时候非常明显。
//server.c
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>#define MAXLINE 10 //最大长度
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 8000
#define INFTIM 1000
#define IP_ADDR "127.0.0.1"int main()
{struct epoll_event ev, events[20];struct sockaddr_in clientaddr, serveraddr;int epfd;int listenfd;//监听fdint maxi;int nfds;int i;int sock_fd, conn_fd;char buf[MAXLINE];epfd = epoll_create(256);//生成epoll句柄listenfd = socket(AF_INET, SOCK_STREAM, 0);//创建套接字ev.data.fd = listenfd;//设置与要处理事件相关的文件描写叙述符ev.events = EPOLLIN;//设置要处理的事件类型epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);//注冊epoll事件memset(&serveraddr, 0, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);serveraddr.sin_port = htons(SERV_PORT);bind(listenfd,(struct sockaddr*)&serveraddr, sizeof(serveraddr));//绑定套接口socklen_t clilen;listen(listenfd, LISTENQ);//转为监听套接字int n;while(1){nfds = epoll_wait(epfd,events,20,500);//等待事件发生//处理所发生的全部事件for(i=0;i<nfds;i++){if(events[i].data.fd == listenfd)//有新的连接{clilen = sizeof(struct sockaddr_in);conn_fd = accept(listenfd, (struct sockaddr*)&clientaddr, &clilen);printf("accept a new client : %s\n",inet_ntoa(clientaddr.sin_addr));ev.data.fd = conn_fd;ev.events = EPOLLIN;//设置监听事件为可写epoll_ctl(epfd, EPOLL_CTL_ADD, conn_fd, &ev);//新增套接字}else if(events[i].events & EPOLLIN)//可读事件{if((sock_fd = events[i].data.fd) < 0)continue;if((n = recv(sock_fd, buf, MAXLINE, 0)) < 0){if(errno == ECONNRESET){close(sock_fd);events[i].data.fd = -1;}else{printf("readline error\n");}}else if(n == 0){close(sock_fd);printf("关闭\n");events[i].data.fd = -1;}printf("%d -- > %s\n",sock_fd, buf);ev.data.fd = sock_fd;ev.events = EPOLLOUT;epoll_ctl(epfd,EPOLL_CTL_MOD,sock_fd,&ev);//改动监听事件为可读}else if(events[i].events & EPOLLOUT)//可写事件{sock_fd = events[i].data.fd;printf("OUT\n");scanf("%s",buf);send(sock_fd, buf, MAXLINE, 0);ev.data.fd = sock_fd;ev.events = EPOLLIN;epoll_ctl(epfd, EPOLL_CTL_MOD,sock_fd, &ev);}}}return 0;
}
参考:https://www.cnblogs.com/cynchanpin/p/7261539.html
socket epoll模型相关推荐
- Linux网络服务器epoll模型的socket通讯的实现(一)
准备写一个网络游戏的服务器的通讯模块,参考网上看到的一些代码,在linux下面实现一个多线程的epoll模型的socket通讯的代码,以下是第一部分多线程的切换代码: 1 #include <s ...
- linux socket编程epoll模型实现群发消息
1.实现功能 本代码主要实现了socket编程epoll模型实现多个客户端连接服务器,客户端可以进行群发消息和接收用户输入文本信息,然后发送该信息给服务器,服务器收到后发送应答信息.客户端接收并显示该 ...
- socket 通信之 epoll模型
//socket 通信之 epoll 模型 #include <sys/epoll.h>struct epoll_event{uint32_t events;//需要检测的fd事件,取值与 ...
- 朴素、Select、Poll和Epoll网络编程模型实现和分析——Poll、Epoll模型处理长连接性能比较
在<朴素.Select.Poll和Epoll网络编程模型实现和分析--模型比较>一文中,我们分析了各种模型在处理短连接时的能力.本文我们将讨论处理长连接时各个模型的性能.(转载请指明出于b ...
- 朴素、Select、Poll和Epoll网络编程模型实现和分析——Epoll模型
在阅读完<朴素.Select.Poll和Epoll网络编程模型实现和分析--Select模型>和<朴素.Select.Poll和Epoll网络编程模型实现和分析--Poll模型> ...
- linux epoll模型
原文:http://yjtjh.blog.51cto.com/1060831/294119 Linux I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数.Linux ...
- Socket拉屎模型之二--实践篇
前言:本篇没有介绍最好的IO模型 epoll(非阻塞异步),是性能最好的.但是本篇不做介绍. http://www.ibm.com/developerworks/cn/linux/l-async/ h ...
- 0729------Linux网络编程----------使用 select 、poll 和 epoll 模型 编写客户端程序
1.select 模型 1.1 select 函数原型如下,其中 nfds 表示的描述符的最大值加1(因为这里是左闭右开区间),中间三个参数分别表示要监听的不同类型描述符的集合,timeout用来表示 ...
- 【转】Epoll模型
Linux 2.6内核中提高网络I/O性能的新方法-epoll I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数. 1.为什么select落后 首先,在Li ...
最新文章
- 无线电能接收初步测试
- 内置哪几种服务容器_ASP.NET CORE 内置的IOC解读及使用
- C/C++程序内存分配详解
- Acwing第 11 场周赛【未完结】
- 一种不通过UI给C4C自定义BO创建测试数据的方式
- react native windows create bundle folder
- 【java】详解java多线程
- 20、Tabs底部导航栏
- Delphi中Hash表的使用方法!
- 一般通话记录能保存多少条_有一手|2万炒股0一般能挣多少?
- matlab sqrtm,zz矩阵开方sqrt()和sqrtm()的区别
- 盛世zeepower远程距离隔空无线充投放商用 低频磁共振无线充电技术——充电有效距离 20-45mm
- STM32的ADC采集实现的信号抓取,然后通过串口传到上位机中显示
- 高等数学几何图形凸优化
- 跟铁拐李李老师学习工作流的第二天
- 合法的python赋值语句_关于Python赋值语句,以下选项中合法的是??()。
- 碉堡了的kotlin扩展函数
- 网页动态蜘蛛网线条特效
- 如何把低像素图片转成高清,分享四个方法给大家!
- 光影软件测试自学,使用set a light 3D STUDIO来学习如何布光②
热门文章
- R语言倾向性匹配得分(Propensity score matching)PSM分析实战
- 玩好大数据:1.数据清洗
- 全面的数据库管理工具——DBeaver Enterprise
- python pip与pip3安装、更新、卸载、查看等常用命令汇总
- 山东计算机春考专科院校分数,2020年山东春季高考专科批第一次志愿录取分数线...
- 汽配行业数字化管理 一键完成订单流转+库存预警+绩效核算
- mouseleave 和 mouseout , mouseenter 和 mouseover,mouseover 和mousemove
- tornado中文手册
- Move 和 SimpleMove
- udev(一)-- 什么是udev