JAVA网络编程

概念

  BIO  阻塞io,1.4之前

  NIO  no-blocking io 非阻塞io,jdk1.4

  AIO  异步io,jdk1.7

 

浏览器输入网址,敲下回车之后发生了什么?

  1.URL解析

    

 

   2.DNS解析

      概念:Domain Name System,域名系统,本质上是一个分布式数据库。将人类可读的域名解析成计算机可读的IP地址

        

      解析顺序:从右向左

          

      域名的层级:类似于索引,一级一级更有效率的查找

           

      DNS查询的两种方式:递归与迭代

            

 

               

 

 

网络协议

      

 

 

各个层的数据包格式

    一个数据包叫一个帧,最大1518字节,经过每个层的时候,会加上特定的标头信息

        

 

 

java.io专业术语

    

 

     

 

     

 

     字符流:相对高级,处理人类可以理解和阅读的字符

    基本字符流:

      

    高级字符流:

        

  字节流:相对低级,处理字节,1字节=8bit

    基本字节流:

        

    高级字节流:

        

  设计模式:装饰者模式,高级流套在低级流之上

        

  Socket

      socket以ip+port作为唯一标识,与网卡驱动进行绑定,实现点对点的通信

      unix系统中,一切皆是文件,socket也不例外,这就是为什么在多路复用模型中,总是会提到文件描述符这个词语了。

      

 

 

       

  同步异步阻塞非阻塞

    一个表白的故事,一个男生向心仪已久的女生表白

      同步:女生想了一段时间,当场给出了自己的答复

          

      异步:女生说,你让我考虑几天,想好了我会打你电话 

          

      阻塞:男生心心念念,茶不思饭不想,一心等待着女生的答复。

         

      非阻塞:男生落落大方,个人生活并没有被表白这一件事情完全占据,等待回复这段时间,正常在做自己的事情,比如打打篮球

          

  线程池

    本质上为了线程复用,银行办理业务的故事

      单线程:只有一个柜员,顾客排队办理业务。

      多线程非线程池:有客户就招柜员,办理完了就辞退柜员,再有新的顾客再重新招聘柜员,这无疑是非常可笑的。

          

      线程池:有一批固定的柜员,平时作为常设窗口提供服务(核心线程数),

          业务繁忙的时候,由HR去招聘一批员工(线程工厂),

          如果窗口已经全部开放(最大线程数),客户仍然很多,就需要在大厅排队办理(工作队列),

          如果业务非常火爆(比如听过银行破产,储户争相取款- -),整个大厅挤满了客户,那么对于其他大厅外的客户,银行只能说no,告知暂时无法提供服务(拒绝策略)

          业务高峰过去之后,新招的员工并不会被立即辞退,只有那些长时间没有业务的员工,才会被HR辞退(空闲时间)

              

          

          java提供的线程池(除此之外 ,还有手动创建,ThreadpoolExecutor、ScheduledThreadpoolExecutor、Fork Join Pool):

          

 

 

 

 

JAVA IO的前世:BIO阻塞模型

      

      

JAVA IO的今生:NIO非阻塞模型

        

 

          

  buffer解析

      channel是读写双向的,依赖buffer来实现,通过flip()方法来实现读/写模式的翻转

      写模式

          

 

       读模式,limit移动到之前写模式的最后一条,position移动到起始位置。即只能读取写模式下写入到buffer中的数据

          

 

       如果数据全部读取完,调用clear()方法重新转换成写模式,limit回到最末尾,position回到起始位置

         clear()方法其实并没有真的去清除buffer中的数据,只是移动了两个指针而已,但是下次再写入的时候,原有数据就会被覆盖,效果上等同于清除,是一个很巧妙而高效的方法

            

      如果数据并未全部读完,在这之前需要先转换成写模式,则调用compact()方法

        compact()方法把之前未读完的数据复制到buffer的最前面,然后把position指向紧跟着的那个位置,从这个位置开始写入新的数据,limit移动到末尾,这样可以确保每次读的时候是从上一次未读取完的位置开始继续读取。

              

  channel解析

      channel之间可以直接进行数据交换

          

 

       几个重要的channel

           

 

   多方法实现文件拷贝

       

        不带缓冲区的字节流拷贝

        带缓冲区的字节流拷贝

        基于channer的buffer进行拷贝

        两个channel之间直接拷贝

  

        性能对比:三个不同大小的文件,小的400K,中等的10M。大的500M,四个拷贝方法均执行5次,取平均值进行比较

             不带缓冲区的字节流拷贝性能非常差,几千倍的差距

             其他三种方法差别不大,随着文件的增大,nio的方法效率相对来说比传统的bufferedStream好一些

             其实传统io的方法实现在新版本的jdk中已经被重写过了,在jdk1.4的时候,nio方法的性能要比传统io好很多,目前主流的jdk1.8中,底层实现差不多,所以性能没有太明显的差距了。

              

  selector解析

        所有的channel注册在selector上面,由selector来监测channel的状态变化

            

 

         channel的状态变化

            connect:socketChannel连接到了服务器上  

            accept:serverSocketChannel接受了一个连接

            read:channel上有数据,处于可读状态

            write:channel处于可写入状态 

              

 

         在Selector上注册channel

            每个channel获得一个唯一的SelectionKey,interestOps()关心的事件,readyOps()就绪的事件

              

        使用selector选择channel

            select()统计所有注册的channel事件就绪的个数,操作完之后需要手动的重置就绪状态,以便当channel再次就绪的时候selector可以正确的统计

        

 

    

  NIO编程模型

      socketServerChannel注册监听accept事件,响应说明有新的socketChannel建立了连接,然后对这个新的socketChannel在selector上注册监听read事件,当read事件就绪的时候(buffer中有可读数据),由selector所在的线程去处理该io请求

      这样,selector所在的这个线程可以同时处理多个io请求,不像BIO模型中每个io请求都需要有一个单独的线程去一对一的阻塞处理

        

JAVA IO的后世之师:AIO异步模型

  内核IO模型

      阻塞式I/O:每次系统调用阻塞,知道成功返回数据为止

             

 

       非阻塞式I/O:不停的进行系统调用,没有数据就直接返回无数据,知道有成功返回为止

            

 

       I/O多路复用:不再由应用程序自身不停的进行系统调用,交由selector来监听事件,事件就绪的时候,会返回可读条件,然后应用程序发起系统调用,成功返回数据

              

 

       异步I/O:前面三种都是同步调用,无论是阻塞还是非阻塞,应用程序必须主动发起系统调用才能得到数据,在异步I/O模型中,应用程序先发起系统调用,如果此时数据没有准备好,

            则返回无数据(非阻塞),当未来的某个时间,内核将数据准备好了之后,就会执行相应的回调函数

               

  异步调用机制    

      AIO中的异步操作

          

 

       异步实现原理

          基于Future,异步阻塞,用于客户端

            

 

           基于CompletionHandler,异步非阻塞,用于服务端 ,底层有一个AsyncronousChannelGroup线程池,用来执行回调函数,性能比nio的单线程同步非阻塞selector更高,AIO模型的精髓也就在这里。

                

 

   AIO编程模型  

      

 

 

 

三种IO模型适用情境      

  

 

 

      

          

      

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

          

 

posted @ 2020-11-14 05:22  红嘴鲤鱼  阅读(90)  评论(0编辑  收藏  举报