文章目录
一、文件描述符与IO模型
二、端口和地址复用
三、select
四、poll
五、epoll
六、相关面试题
1、epoll读到一半又有新事件来了怎么办?
一、文件描述符与IO模型
  文件描述符:当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。

  IO多路复用是一种同步IO模型,实现一个进程可以监视多个文件句柄(socket、文件或者管道等等),一旦某个文件句柄就绪,就能够通知程序进行相应的读写操作。

  IO多路复用相比于多线程的优势在于系统的开销小,系统不必创建和维护进程或线程,免去了线程或进程的切换带来的开销。而操作系统支持IO多路复用的系统调用有select,poll和epoll。

二、端口和地址复用
  在默认的情况下,如果一个网络应用程序的一个套接字绑定了一个端口( 8080),这时候,别的套接字就无法使用这个端口( 8080 )。

  但是端口复用允许在一个应用程序可以把多个套接字绑在一个端口上而不出错。通过设置socket的SO_REUSEADDR选项,即可实现端口复用:

int opt = 1;  
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 
          (const void *)&opt, sizeof(opt));  
1
2
3
【为什么要有这个端口复用呢】 ?

  因为在服务端结束后,也就是第三次挥手的时候会有个等待释放时间(time_wait),这个时间段大概是1-4分钟(2MSL), 在这个时间内,端口不会迅速的被释放,所以可通过端口复用的方法来解决这个问题。

  SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个socket绑定的ip地址不同。

【为什么一个端口可以建立多个连接】 ?

  一个TCP连接需要由四元组来形成,即(src_ip,src_port,dst_ip,dst_port)。
假设有客户端建立了连接(src_ip1,src_port1,dst_ip1,dst_port1),那么,如果我们还有listen在(src_ip1,src_port1),那么当(dst_ip1,dst_port1)发送消息过来,系统应该把消息给谁?所以就说明了客户端占用了某一端口时,该端口就不能被其它进程listen了。

  作为一个服务器监控一个端口,比如80端口,它为什么可以建立上百万个连接?首先要明白一点,当accept出来后的新socket,它所占用的本地端口依然是80端口,很多新手都以为是一个新的随机端口。由四元组就很容易分析到了,同一个(src_ip,src_port),它所对应的(dst_ip,dst_port)可以无穷变化,这样就可以建立很多个客户端的请求了。

三、select
int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 
            struct timeval *timeout);
1
2
  select的底层是一个fd_set的数据结构,本质上是一个long类型的数组,数组中每一个元素都对应于一个文件描述符,通过轮询所有的文件描述符来检查是否有事件发生。

【优点】:

可移植性好;

连接数少并且连接都十分活跃的情况下,效率也不错。

【缺点】:

可以监听的最大文件描述符数量为1024(因为内核写定了)。

检查是否有事件发生是采用轮询遍历的方式,当文件描述符很多时开销很大。

四、poll
int poll(struct pollfd* fds, unsigned int nfds, int timeout);
1
  poll与select差不多,但poll的文件描述符没有最大数量的限制,但是依然采用轮询遍历的方式检查是否有事件发生。

五、epoll
// 返回epoll文件描述符,size表示要监听的数目 (这个返回的fd要记得close)
int epoll_create(int size); 
// epoll事件注册函数
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); 
// 等待事件发生,events是返回的事件链表
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);  
1
2
3
4
5
6
  epoll是一种更加高效的IO多路复用的方式,它可以监视的文件描述符数量突破了1024的限制(十万),同时不需要通过轮询遍历的方式去检查文件描述符上是否有事件发生,因为epoll_wait返回的就是有事件发生的文件描述符。本质上是事件驱动。

  具体是通过红黑树和就绪链表实现的,红黑树存储所有的文件描述符,就绪链表存储有事件发生的文件描述符;

epoll_ctl可以对文件描述符结点进行增、删、改、查,并且告知内核注册回调函数(事件)。

一旦文件描述符上有事件发生时,那么内核将该文件描述符节点插入到就绪链表里面

这时候epoll_wait将会接收到消息,并且将数据拷贝到用户空间。

  表面上看epoll的性能最好,但是在连接数少并且连接都十分活跃的情况下,select和poll的性能可能比epoll好,毕竟epoll的通知机制需要很多函数回调。

六、相关面试题
1、epoll读到一半又有新事件来了怎么办?
  避免在主进程epoll再次监听到同一个可读事件,可以把对应的描述符设置为EPOLL_ONESHOT,效果是监听到一次事件后就将对应的描述符从监听集合中移除,也就不会再被追踪到。读完之后可以再把对应的描述符重新手动加上。
————————————————
版权声明:本文为CSDN博主「lx青萍之末」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/daaikuaichuan/article/details/88735256

Java网络编程与NIO详解13:epoll、poll、select面试题汇总相关推荐

  1. Java网络编程与NIO详解14:Tomcat 常见面试题汇总

    1.Tomcat的缺省端口是多少,怎么修改? 1)找到Tomcat目录下的conf文件夹 2)进入conf文件夹里面找到server.xml文件 3)打开server.xml文件 4)在server. ...

  2. Java网络编程和NIO详解开篇:Java网络编程基础

    老曹眼中的网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为我们拥有网络.网络是一个神奇的东西,它改变了你和我的 ...

  3. Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制

    JAVA 中原生的 socket 通信机制 转载自:https://github.com/jasonGeng88/blog 当前环境 jdk == 1.8 知识点 socket 的连接处理 IO 输入 ...

  4. connect: 网络不可达_Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制

    本文转自:https://github.com/jasonGeng88/blog 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https ...

  5. java httputil_Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型

    本文转载自:https://github.com/jasonGeng88/blog 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 http ...

  6. Visual C++网络编程经典案例详解 第9章 实用播放器 数据读取与播放控制 识别数据文件信息

    识别数据文件信息主要是指对mp3数据格式识别 定义顺序代码如下 typedef struct mp3_struct //自定义mp3结构体 {char heade[3]; //tag字符标记char ...

  7. Java网络编程与NIO学习总结

    #Java网络编程与NIO学习总结 这篇总结主要是基于我之前Java网络编程与NIO系列文章而形成的的.主要是把重要的知识点用自己的话说了一遍,可能会有一些错误,还望见谅和指点.谢谢 #更多详细内容可 ...

  8. Java并发编程最佳实例详解系列

    Java并发编程最佳实例详解系列: Java并发编程(一)线程定义.状态和属性 Java并发编程(一)线程定义.状态和属性 线程是指程序在执行过程中,能够执行程序代码的一个执行单元.在java语言中, ...

  9. java mysbatis select_java相关:详解Mybatis中的select方法

    java相关:详解Mybatis中的select方法 发布于 2020-7-3| 复制链接 摘记: selectById方法根据id,查询记录 ```java public void updateRe ...

最新文章

  1. 写一个测试工具类,只在debug时运行,而release时自动移除代码,适用于gradle项目(idea,android studio等)
  2. eclipse中导入spring-boot框架的jar包方法
  3. Java的主要就业方向
  4. 基于百度理解与交互技术实现机器问答
  5. 一个成功的研发团队应具备的9大属性
  6. JVM&NIO&HashMap简单问
  7. 好家伙!QQ正在读取你所有的浏览器历史记录?腾讯致歉后,网友评论绝了
  8. 翻译:SET PASSWORD语句(已提交到MariaDB官方手册)
  9. Python之面向对象进阶篇
  10. mysql 数据类型总结
  11. 异贝,通过移动互联网技术,为中小微实体企业联盟、线上链接、线上线下自定义营销方案推送。案例32
  12. svnserver 重新启动
  13. params.c:Parameter() - Ignoring badly formed line in configuration file: ignore errors 解决方法
  14. 软件工程保研成功率_软件工程专业保研还是工作?
  15. 黑群晖二合一安装不了套件_家庭NAS部署指南(二)——如何自己动手安装一台黑群晖主机...
  16. matlab 采样开关,UPS单模块10kVA单相电压型SPWM逆变器的Simulink模型建立及仿真分析...
  17. Android 类似360 系统启动时间提示
  18. SEP12.1.2现在支持自动卸载其他某些杀毒软件
  19. 两个摄像头合成一路_两个摄像头怎样用一个显示屏
  20. 小米笔记本“突然”不能调整屏幕亮度

热门文章

  1. 『JAX中文文档』JAX快速入门
  2. Nginx安装启动后无法访问(访问拒绝连接)
  3. We~ˇsay~~ˇ
  4. 企业资产管理,这么用事半功倍!
  5. NFC芯片-通用协议标准
  6. SAP中基于收货的发票校验配置过程
  7. 软件问题造成的经济损失案例_案例研究:危害计算机信息系统的行为性质分析与损失认定...
  8. [渝粤教育] 西南政法大学 经济法学 参考 资料
  9. Dubbo Monitor 配置
  10. RecBole小白入门系列博客(二) ——General类模型运行流程