I/O模型之BIO到NIO到select

socket:客户端请求与服务器端建立连接 

客户端通过socket发起连接请求,在服务器端由socket listen负责监听客户端请求,收到后通过bind和accept建立对应的通信套接字socket。(accept和read/write默认是会阻塞的)

BIO(同步阻塞,单线程不并发,并发一定阻塞,多线程高并发但是有缺点)服务器需要监听端口号,客户端通过IP和端口与服务器建立TCP连接,以同步阻塞的方式传输数据。服务器端一般是客户端-线程模型,即新来一个客户端连接请求就新建一个线程处理连接和数据传输。客户端连接较多时会大大消耗服务器资源,线程数可能超过最大承受量。

  • 如果采用单线程—无法处理并发服务器()—因为accept和read/write(此时客户端还没发数据过来)会阻塞。
  • 如果采用多线程—完成并发处理—变成子线程自己阻塞?缺点:并发时,需要开很多线程,线程需要上下文切换,不好控制,多线程有哪些缺点?。实际情况下很多客户端连接了但是并不发生磁盘I/O,这种情况下多线程开了很多线程就会造成很多资源浪费。实际上有80%的客户端都不发生I/O比如淘宝。

NIO(同步非阻塞,单线程高并发)因为BIO采用单线程无法处理高并发客户请求(因为accept和R/W会阻塞),采用多线程的话很可能造成资源浪费。所以,NIO是对BIO的改进,即设计能够用单线程处理高并发的请求(不采用多线程)。NIO的改进主要有两点:一点是将accept和R/W设置为非阻塞模式;另一点是设置一个list集合(或者数组),将所有客户端请求时创建的socket添加进该list集合(或者数组)中,在socketsever监听客户端请求时,通过while(true){}循环来达到处理高并发(假多线程)的目的。在循环中不断轮询list集合中的socket,判断是否有客户端发送了数据过来。整个过程全部发生在应用程序(APPsever)中。如图:

全程使用一个线程来轮询所有socket的i/o事件,适合高并发、高负载的网络应用,充分利用系统资源快速处理请求返回响应信息,适合连接较多、I/O任务时间短的场景。没有在内核中。

Select在NIO中,list集合中的所有通信socket是在用户态的,运行在应用程序(APPsever)中的,这样,应用程序就要处理很大的socket数量。而select是在NIO的基础上将list套接字集合由用户空间全部复制到内核空间,由内核来完成对所有socket的轮询,当发现客户端有数据发送过来,由内核进行相应socket的I/O操作。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值