I/O多路复用方案

1.本节思维导图2.基本的网络编程接口2.1基于TCP的通信模型2.2基于UDP的通信模型3.非阻塞的服务器程序file、pipe、fifo、socket在默认创建过程中都是阻塞的

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

1. 本节思维导图

  I/O多路复用方案

2. 基本的网络编程接口

2.1 基于TCP的通信模型

  I/O多路复用方案

2.2 基于UDP的通信模型

I/O多路复用方案

3. 非阻塞的服务器程序

  file、pipe、fifo、socket在默认创建过程中都是阻塞的(block),非阻塞的接口相比于阻塞型接口的显著差异在于,在被调用之后立即返回,在linux中我们可以使用fcntl()函数来设置描述符的状态

  fcntl(fd,F_SETFL, O_NOBLOCK)

  fcntl函数重点关注第二个参数中的F_SETFL和F_GETFL设置或获取描述符的状态

  状态包括:O_NONBLOCK O_APPEND O_ASYNC

  O_DIRCT(最小化或去掉reading和writing的缓存影响.系统将企图避免缓存你的读或写的数据)

  在非阻塞的状态下,recv()接口在被调用后立即返回,返回值代表了不同的含义:

1)recv()返回值大于0,表示接收数据完毕,返回值即是接收到的字节数
(2)recv()返回值为0,表示链接已经正常断开
(3)recv()返回值为-1,且errno等于EAGAIN,表示recv操作还没有执行完成
(4)recv()返回值为-1,且error不等于EAGAIN,表示recv操作遇到系统错误errno

  注意:绝不推荐循环调用recv()来检测“操作是否完成”,循环调用recv将大幅度推高CPU占用率,实际操作系统提供了更为高效的方法来检测“操作是否完成”,比如select、epoll

4. select()接口的基于事件驱动的服务器模型

  大部分UNIX/LINUX都支持select函数,改函数用于探测多个文件句柄的状态变化,以下为select接口的原型:

FD_ZERO(int fd, fd_set *fds) // fd_set类型变量的所有位都设为0
FD_SET(int fd, fd_set *fds ) // 设置变量的某个位置位
FD_ISSET(int fd, fd_set *fds) // 测试某个位置是否被置位
FD_CLR(int fd, fd_set *fds)   // 清除某个位时可以使用
int select(int nfds, fd_set *readfds, fd_set *writefds, df_set *exceptfds, struct timeval *timeout)

  关于select更加详细的说明和使用请参考:https://www.cnblogs.com/skyfsm/p/7079458.html

5. 使用epoll实现异步事件通知模型

  已经在前面的博客中总结了epoll用法,具体参考:linux之epoll

  这里重点说明下accept的使用技巧:

  (1)阻塞模式accept存在的问题,考虑这种情况:TCP链接被客户端夭折,即在服务器调用accept之前,客户端主动发送RST终止链接,导致刚刚建立的链接从就绪队列中移除,如果套接口被设置为阻塞模式,服务器就会一直阻塞在accept调用上,直到其它某个客户端建立一个新的链接为止,但是在此期间,服务器单纯地阻塞在accept调用上,就需队列中的其它描述符都得不到处理

  解决方法:把监听套接口设为非阻塞,当客户端在服务器调用accept之前中止某个连接时,accept调用可以立即返回-1,这时源自Berkeley的实现会在内核中处理该事件,并不会将该事件同质epoll。而其它实现把errno设置为ECONNABORTED或者EPROTo错误,我们可以忽略这两个错误。

  (2)ET模式相爱的accept存在的问题,考虑这种情况:多个链接同时到达时,服务器的TCP就绪队列瞬间基类多喝就绪链接,由于是边缘触发模式,epoll只会通知一次,accept只处理第一个链接,导致TCP就绪队列中剩下的链接都得不到处理

  解决方法:用while循环包住accept,处理完TCP就绪队列中的所有链接后再退出循环,如何知道是否处理完就绪队列中的所有链接呢?accept返回-1并且errno设置为EAGAIN就表示所有的链接都处理完。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120104.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • eagle-eye介绍

    eagle-eye介绍简介淘宝现在是一个由很多个应用集群组成的非常复杂的分布式系统。这些应用里面主要有处理用户请求的前端系统和有提供服务的后端系统等。这些应用之间一般有RPC调用和异步消息通讯两种手段,RPC调用会产生一层调一层的嵌套,一个消息发布出来更会被多个应用消费,另外,应用还会访问分库分表的数据库、缓存、存储等后端,以及调用其他外部系统如支付、物流、机彩票等。请试想一下,现在淘宝一个买家点击下单按…

    2022年8月16日
    9
  • Eclipse使用技巧–代码自动补全功能

    Eclipse使用技巧–代码自动补全功能1、在“触发代码提示”允许的范围之内,空格键和回车键就是快捷键。2、补全代码功能需设置“AutoActivationtriggersforjava”。3、“AutoActivationtriggersforjava”这个选项就是指触发代码提示的的选项,把“.”改成“.abcdefghijklmnopqrstuvwxyz(”的意思,就是指遇到26个字母和“.与(”这些符号就触发代码提示功能了。4、代码提示选项补充完整后,输入关键字即可得到提示功能,得到提示功能后,回车键与空格键就是

    2022年5月31日
    44
  • ***R解压密码[通俗易懂]

    3.8ACG3201660CG34.0DpopkingsV2EXsquidgfw转载于:https://www.cnblogs.com/zhuxiaoxi/p/7452350.html

    2022年4月9日
    73
  • ASP官网_什么是ASP.NET?它有什么优势

    ASP官网_什么是ASP.NET?它有什么优势asp转换时区的问题原代码,strDateTime=now()因空间是美国的,这样获得的是美国的时间怎样写,可以转换成北京时间美西时间为西8区,北京时间为东8区也就是说美西时间比北京时间慢16个小时所以,北京时间=美西时间+16小时得到:strDateTime=DateAdd(“h”,16,now())插曲:美国共有四个时区:西部

    2022年10月7日
    5
  • 图像处理的Dither和Banding「建议收藏」

    图像处理的Dither和Banding「建议收藏」由于前面的文章涉及到了这两个概念,而我又对图像处理一窍不通,所以专门写一篇文章来了解这两个概念。Colourbanding       banding是计算机图形中颜色表现不精确的一个问题。DitherDither(抖动)是一种故意造成的噪音用以随机化量化误差,阻止大幅度拉升图像时导致的像banding(色带)这样的问题.Dither概念常用在

    2022年10月13日
    3
  • InnoDB中的索引类型

    InnoDB中的索引类型InnoDB数据引擎使用B+树构造索引结构,其中的索引类型依据参与检索的字段不同可以分为主索引和非主索引;依据B+树叶子节点上真实数据的组织情况又可以分为聚族索引和非聚族索引。每一个索引B+树结构都会有一个独立的存储区域来存放,并且在需要进行检索时将这个结构加载到内存区域。真实情况是InnoDB引擎会加载索引B+树结构到内存的BufferPool区域。聚簇索引(聚集索引)聚簇索引指的是这样的数据组织结构:索引B+树的每个叶子节点直接对应了真实的DataPage。并且B+树所有的叶子节点在最底层共同描

    2022年6月1日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号