linux epoll系列1 创建epoll

据说select和poll的弱点是,随着连接(socket)的增加,性能会直线下降。

epoll不会随着连接(socket)的增加,性能直线下降。

知识点:

1,epoll_wait函数是阻塞的,直到有socket发生变化。

2,epoll使用流程,先创建(epoll_create),再把socket添加到epoll里(epoll_ctl),然后等待socket的变化(epoll_wait)

接收端,接收2个socket

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <arpa/inet.h> #define EVENTS 12 int main(){
int sock1, sock2;
sockaddr_in addr1, addr2;
int epfd;
epoll_event ev, ev_ret[EVENTS];
char buf[2048];
int i;
int nfds;
int n; //创建2个接受消息的socket
sock1 = socket(AF_INET, SOCK_DGRAM, 0);
sock2 = socket(AF_INET, SOCK_DGRAM, 0);
addr1.sin_family = AF_INET;
addr2.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &addr1.sin_addr.s_addr);
inet_pton(AF_INET, "127.0.0.1", &addr2.sin_addr.s_addr); addr1.sin_port = htons(11111);
addr2.sin_port = htons(22222); bind(sock1, (sockaddr*)&addr1, sizeof(addr1));
bind(sock2, (sockaddr*)&addr2, sizeof(addr2)); //参数不小于0就行
epfd = epoll_create(1);
if(epfd < 0){
perror("epoll_create");
return 1;
} memset(&ev, 0, sizeof(ev));
ev.events = EPOLLIN;//只读
ev.data.fd = sock1;//把sock1加到epoll
if(epoll_ctl(epfd, EPOLL_CTL_ADD, sock1, &ev) != 0){
perror("epoll_ctl");
return 1;
} memset(&ev, 0, sizeof(ev));
ev.events = EPOLLIN;//只读
ev.data.fd = sock2;//把sock2加到epoll
if(epoll_ctl(epfd, EPOLL_CTL_ADD, sock2, &ev) != 0){
perror("epoll_ctl");
return 1;
} while(1){
printf("before epoll_wait\n");
//在这里会阻塞,直到有socket进来.
nfds = epoll_wait(epfd, ev_ret, EVENTS, -1);
if(nfds <= 0){
perror("epoll_wait");
return 1;
} printf("after epoll_wait\n"); for(i = 0; i < nfds; ++i){
//判断进来的socket是哪个socket
if(ev_ret[i].data.fd == sock1){
//从sock1读取数据,并写入到标准输出
n = recv(sock1, buf, sizeof(buf), 0);
write(fileno(stdout), buf, n);
}
//判断进来的socket是哪个socket
else if(ev_ret[i].data.fd == sock2){
//从sock1读取数据,并写入到标准输出
n = recv(sock2, buf, sizeof(buf), 0);
write(fileno(stdout), buf, n);
}
}
} close(sock1);
close(sock2);
return 0;
}

github源代码

发送端,向2个地址发送信息

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <arpa/inet.h> int main(){
int sock;
sockaddr_in dest1, dest2;
char buf[1024]; sock = socket(AF_INET, SOCK_DGRAM, 0); dest1.sin_family = AF_INET;
dest2.sin_family = AF_INET; inet_pton(AF_INET, "127.0.0.1", &dest1.sin_addr.s_addr);
inet_pton(AF_INET, "127.0.0.1", &dest2.sin_addr.s_addr); dest1.sin_port = htons(11111);
dest2.sin_port = htons(22222); strcpy(buf, "data to port 11111\n");
//给地址1(dest1)送信
sendto(sock, buf, strlen(buf), 0, (sockaddr*)&dest1, sizeof(dest1)); strcpy(buf, "data to port 22222\n");
//给地址2(dest2)送信
sendto(sock, buf, strlen(buf), 0, (sockaddr*)&dest2, sizeof(dest1)); close(sock); return 0;
}

github源代码

运行方法:

先运行接收端,结果如下:

before epoll_wait

再运行发送端,结果如下:

before epoll_wait
after epoll_wait
data to port 11111
before epoll_wait
after epoll_wait
data to port 22222
before epoll_wait

从运行结果可以看出:在epoll_wait处,程序的停住的,也就是阻塞的状态,但是当运行发送端后,马上就变成了非阻塞状态,也就实现了,处理多个socket的请求,而并没有使用多进程,或者多线程。

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

c/c++ linux epoll系列1 创建epoll的更多相关文章

  1. c/c++ linux epoll系列3 利用epoll_wait设置timeout时间长度

    linux epoll系列3 利用epoll_wait设置timeout时间长度 epoll_wait函数的第四个参数可以设置,epoll_wait函数的等待时间(timeout时间长度). 例子1, ...

  2. Linux NIO 系列(04-3) epoll

    目录 一.why epoll 1.1 select 模型的缺点 1.2 epoll 模型优点 二.epoll API 2.1 epoll_create 2.2 epoll_ctl 2.3 epoll_ ...

  3. Linux NIO 系列(04-4) select、poll、epoll 对比

    目录 一.API 对比 1.1 select API 1.2 poll API 1.3 epoll API 二.总结 2.1 支持一个进程打开的 socket 描述符(FD)不受限制(仅受限于操作系统 ...

  4. c/c++ linux epoll系列2 利用epoll_wait查看是否可以送信

    linux epoll系列2 利用epoll_wait查看是否可以送信 write函数本来是非阻塞函数,但是当缓存区被写满后,再往缓存区里写的时候,就必须等待缓存区再次变成可写,所以这是write就变 ...

  5. epoll 系列函数简介、与select、poll 的区别

    一.epoll 系列函数简介 #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags) ...

  6. IO复用——epoll系列系统调用

    1.内核事件表 epoll是Linux特有的I/O复用函数.epoll把用户关心的文件描述上的事件放在内核里的一个事件表中,并用一个额外的文件描述符来标识该内核事件表.这个额外文件描述符使用函数epo ...

  7. [转载] Linux下多路复用IO接口 epoll select poll 的区别

    原地址:http://bbs.linuxpk.com/thread-43628-1-1.html 废话不多说,一下是本人学习nginx 的时候总结的一些资料,比较乱,但看完后细细揣摩一下应该就弄明白区 ...

  8. Linux企业级开发技术(2)——epoll企业级开发之epoll接口

    epoll的接口非常简单,总共只有三个函数: 1.int epoll_create(intsize); 生成一个 Epoll 专用的文件描述符,size用来告诉内核这个监听的数目一共有多大.这个参数不 ...

  9. Linux下select, poll和epoll IO模型的详解

    http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll 介绍 Epoll 可是当前在 Linux 下开发大规模并发网络程序的热 ...

随机推荐

  1. Python—day13 迭代器、迭代器对象、for循环对象、生成器、枚举对象

    一.迭代器 1.迭代器概念: 器:包含了多个值的容器 迭代:循环反馈(一次从容器在取出一个值) 迭代器:从装有多个值的容器在一次取出一个值 ls=[3,5,7,1,9] 遍历:被遍历的对象必须是有序容 ...

  2. 使用 C# 代码实现拓扑排序

    0.参考资料 尊重他人的劳动成果,贴上参考的资料地址,本文仅作学习记录之用. https://www.codeproject.com/Articles/869059/Topological-sorti ...

  3. Python内置函数(65)——type

    英文文档: class type(object) class type(name, bases, dict) With one argument, return the type of an obje ...

  4. Java String:重要到别人只能当老二的字符串类

    字符串,是Java中最重要的类.这句肯定的推断不是Java之父詹姆斯·高斯林说的,而是沉默王二说的,因此你不必怀疑它的准确性. 关于字符串,有很多的面试题,但我总觉得理论知识绕来绕去没多大意思.你比如 ...

  5. Java异常处理:给程序罩一层保险

    文/沉默王二 人这一生,总会遇到一些不可预料的麻烦,这些麻烦可能会让我们遭受沉重的打击.为了减轻因此承受的负担,我们就会买保险. 本着负责任的态度,我们程序员在写代码的时候,都非常的严谨.但程序在运行 ...

  6. EF三种编程方式图文详解

    Entity Framework4.1之前EF支持“Database First”和“Model First”编程方式,从EF4.1开始EF开始支持支持“Code First”编程方式,今天简单看一下 ...

  7. C++中 引用&与取地址&的区别

    微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...

  8. 前端笔记之jQuery(下)事件&节点操作&净位置&拖拽&页面卷动值&遍历JSON

    一.监听事件大全 1.1 JavaScript事件 onblur 元素失去焦点 onchange 用户改变域的内容 onclick 鼠标点击某个对象 ondblclick 鼠标双击某个对象 onfoc ...

  9. 如何优雅的使用 Angular 表单验证

    随便说说,这一节可以跳过 去年参加 ngChine 2018 杭州开发者大会的时候记得有人问我: Worktile 是什么时候开始使用 Angular 的,我说是今年(2018年) 3 月份开始在新模 ...

  10. 滚动 docker 中的 nginx 日志

    Nginx 自己没有处理日志的滚动问题,它把这个球踢给了使用者.一般情况下,你可以使用 logrotate 工具来完成这个任务,或者如果你愿意,你可以写各式各样的脚本完成同样的任务.本文笔者介绍如何滚 ...