BIO和NIO

一、关于tcp/ip协议

 

        tcp/ip四层协议模型自上向下依次是:应用层、传输层、网络层、链路层。

        对于一个网络请求:http://127.0.0.1:8080/

        其中的ip127.0.0.1可以确定主机,端口8080确定主机上的进程,http确定应用层报文的格式。

注意:对于同一种传输协议(tcp),一个进程可以占多个端口,但一个端口只能属于一个进程。

以应用程序发送json报文为例,逻辑上会从上向下进行层层包装:

  1. http协议为json报文加上请求头,把json字符串放到请求体中,形成http结构的报文字符串。http协议不关心应用要发的报文是json格式还是xml格式。
  2. tcp协议给http报文加上tcp头,tcp只管发送字节,不关心上层是http还是其他格式字符串或者图片之类。
  3. ip协议给tcp报文加上ip包的数据,链路层以此类推。

注意:看起来好像json和http不是同一层,但实际上因为应用层的代码是直接调操作系统的tcp相关api(socket),所以直接把json送给tcp层是完全可以的,就是相当于应用层协议是自定义的json格式而已。

二、关于网络IO,阻塞和非阻塞

        网络IO编程主要是面向传输层和应用层。以tcp为例,主要的io操作包括建立连接、读、写,服务端监听一个端口,多个客户端可以来连接,同一个主机也可以通过多个端口来连接服务端,只要保证客户端的ip和端口不完全相同即可建立一条连接。

        不论客户端还是服务端,唯一确定一条连接的数据称为四元组:我方ip、我方端口、对方ip、对方端口:

        对于阻塞和非阻塞,以socket的read数据为例:

        阻塞io:如果对方并没有发送数据,则read方法会阻塞等待,直到有了数据可读,再返回读到的数据。

        非阻塞io:read读取数据会立即返回,如果有数据可读,返回的就是读到的数据,如果没有数据可读,返回一个错误或标识,总之不会在read方法中阻塞等待。

注意:NIO不是操作系统层面的概念,操作系统只是提供api可以设置io阻塞还是非阻塞,以及提供了多路复用的功能。

三、BIO开发模式

        绑定端口后,第2步accept操作会阻塞,直到有客户端发起建立连接,之所以放到死循环中,是为了能不断建立新连接。把新建立的连接socket送给一个新线程来使用,防止对其进行io操作时阻塞主线程导致无法建立新连接。

四、NIO和多路复用

        Java提供了对应的api来设置io为非阻塞,设为非阻塞之后,包括accept、read、write所有的io操作执行时都会立即返回,以accept方法为例,如果没有客户端过来建立连接,则方法返回null。这样线程是不阻塞了,但会有一个明显的问题:应该在什么时候调用accept、read方法(先不考虑write)?我们不确定对方什么时候发来数据,如果要编码来经常调用看看有没有数据进来,实时性不好又很麻烦。如果要在一个死循环中不停轮询,线程又相当于阻塞了干不了别的事,既蠢又浪费性能。

        配合非阻塞io一起使用的技术——多路复用器(Selector):

        每个多路复用器独占一个线程,但是一个多路复用器上可以注册多个socket,多路复用器执行select方法筛选出有io事件的socket,如果其中的socket全都没有io事件,select方法阻塞。这样就相当于把BIO中一个socket阻塞一个线程变成了NIO中多个socket阻塞一个线程,就实现了在非阻塞io中,使用少量线程处理大量连接。因为多个socket共用一个线程,所以实际应用中业务逻辑部分可能会从线程池中取一个线程来处理,避免多路复用器线程被某个业务逻辑独占导致其它的socket数据迟迟处理不了。

        显然,NIO编程难度远大于BIO,不仅需要熟悉非阻塞io、多路复用相关的api,还需要熟练掌握多线程,甚至可能需要解决应用层的问题,不像BIO每个连接有自己独立的线程,如果用NIO开发类似http这种请求响应类的协议,请求和响应的对应关系也必须仔细设计一番。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坏猫警长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值