Nio Server实现

项目GitHub地址:https://github.com/scientist272/non-blocking-server

nio 与阻塞式io

nio即non-blocking io,在网络编程中,相对于传统的阻塞式io,nio只需要一个或者几个线程就能处理大量并发的socket请求,而传统的阻塞式io处理大量并发请求时,很多时候需要为每一个请求创建一条新线程,对于很多长时间保持socket连接但是不发送数据的请求,为它们申请大量线程会造成资源浪费。

传统阻塞式io:

在这里插入图片描述
服务器持续调用accept方法接收socket连接,如果当前没有连接,则一直阻塞到有请求connect到服务器为止。但是这种io会有问题,如图中,当一个请求连接到服务器后,如果它一直什么事都不做,服务器需要等待它的write方法发送数据,这时候会造成处理线程的阻塞,服务器无法处理其他socket的连接请求。
解决方法:为每一个socket请求创建一条处理线程
但是这种方法还是有很大的缺点:即之前提到的,如果有很多请求一直保持和服务器的连接,但却不做任何事,会造成大量的服务器资源浪费。

nio(非阻塞式io)

nio的解决思路:
服务器保持一个或几个线程,通过selector(选择器)来处理大量并发请求。
在这里插入图片描述
开启一个serverSocketChannel,将它注册到selector中,操作为SelectionKey.OP_ACCEPT,即监听接收就绪的socket(有socket连接服务器时,selector就会知道,之后可对它们就行读就绪注册,写就绪注册等)。调用selector的selectNow()方法,这是一个非阻塞的native方法,它会选择出当前所有可操作的socketChannel,包括acceptable,readable,writeable等,即接收就绪,读就绪,写就绪的通道。
简而言之,就是服务器在一个线程中循环调用selectNow()方法,当有socket请求连接服务器时,就对它就行注册,注册完之后就做其他事去了,比如处理其他之前注册的socket请求发送的数据,等这个新连接的socket有数据时,才对它进行处理。

实现思路

服务器用两个线程来工作,一个线程负责接收新的socket,然后将它们加入到一个工作队列中,另一个负责处理socket的线程从工作队列中获取socket并对它们进行注册。
在这里插入图片描述
处理线程会对每一个注册的socket创建一个messageReader实例来读取它们的数据并解析,一个messageWriter负责服务器向它们返回数据。整个处理流程如下图所示
在这里插入图片描述
对请求的数据存储用了一个可变的缓冲区数据结构,其中的byte数组用于存储数据,循环队列用于记录byte数组可用的数据块。
具体实现见GitHub代码,有详细注释。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值