`

底层网络读写

阅读更多

Java NIO:NIO概述

      http://www.cnblogs.com/dolphin0520/p/3919162.html

  在上一篇博文中讲述了几种IO模型,现在我们开始进入Java NIO编程主题。NIO是Java 4里面提供的新的API,目的是用来解决传统IO的问题。本文下面分别从Java NIO的几个基础概念介绍起。

  以下是本文的目录大纲:

  一.NIO中的几个基础概念

  二.Channel

  三.Buffer

  四.Selector

  若有不正之处,请多多谅解并欢迎批评指正。

  请尊重作者劳动成果,转载请标明原文链接:

   http://www.cnblogs.com/dolphin0520/p/3919162.html

一.NIO中的几个基础概念

  在NIO中有几个比较关键的概念:Channel(通道),Buffer(缓冲区),Selector(选择器)。

  首先从Channel说起吧,通道,顾名思义,就是通向什么的道路,为某个提供了渠道。在传统IO中,我们要读取一个文件中的内容,通常是像下面这样读取的:

1
2
3
4
5
6
7
8
9
public class Test {
    public static void main(String[] args) throws IOException  {
        File file = new File("data.txt");
        InputStream inputStream = new FileInputStream(file);
        byte[] bytes = new byte[1024];
        inputStream.read(bytes);
        inputStream.close();
    }  
}

   这里的InputStream实际上就是为读取文件提供一个通道的。

  因此可以将NIO 中的Channel同传统IO中的Stream来类比,但是要注意,传统IO中,Stream是单向的,比如InputStream只能进行读取操作,OutputStream只能进行写操作。而Channel是双向的,既可用来进行读操作,又可用来进行写操作。

  Buffer(缓冲区),是NIO中非常重要的一个东西,在NIO中所有数据的读和写都离不开Buffer。比如上面的一段代码中,读取的数据时放在byte数组当中,而在NIO中,读取的数据只能放在Buffer中。同样地,写入数据也是先写入到Buffer中。

  下面介绍一下NIO中最核心的一个东西:Selector。可以说它是NIO中最关键的一个部分,Selector的作用就是用来轮询每个注册的Channel,一旦发现Channel有注册的事件发生,便获取事件然后进行处理。

  比如看下面的这个例子:

   

  用单线程处理一个Selector,然后通过Selector.select()方法来获取到达事件,在获取了到达事件之后,就可以逐个地对这些事件进行响应处理。

二.Channel

  在前面已经提到,Channel和传统IO中的Stream很相似。虽然很相似,但是有很大的区别,主要区别为:通道是双向的,通过一个Channel既可以进行读,也可以进行写;而Stream只能进行单向操作,通过一个Stream只能进行读或者写;

  以下是常用的几种通道:

  • FileChannel
  • SocketChanel
  • ServerSocketChannel
  • DatagramChannel

  通过使用FileChannel可以从文件读或者向文件写入数据;通过SocketChannel,以TCP来向网络连接的两端读写数据;通过ServerSocketChanel能够监听客户端发起的TCP连接,并为每个TCP连接创建一个新的SocketChannel来进行数据读写;通过DatagramChannel,以UDP协议来向网络连接的两端读写数据。

  下面给出通过FileChannel来向文件中写入数据的一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test {
    public static void main(String[] args) throws IOException  {
        File file = new File("data.txt");
        FileOutputStream outputStream = new FileOutputStream(file);
        FileChannel channel = outputStream.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        String string = "java nio";
        buffer.put(string.getBytes());
        buffer.flip();     //此处必须要调用buffer的flip方法
        channel.write(buffer);
        channel.close();
        outputStream.close();
    }  
}

   通过上面的程序会向工程目录下的data.txt文件写入字符串"java nio",注意在调用channel的write方法之前必须调用buffer的flip方法,否则无法正确写入内容,至于具体原因将在下篇博文中具体讲述Buffer的用法时阐述。

三.Buffer

  Buffer,故名思意,缓冲区,实际上是一个容器,是一个连续数组。Channel提供从文件、网络读取数据的渠道,但是读取或写入的数据都必须经由Buffer。具体看下面这张图就理解了:

  上面的图描述了从一个客户端向服务端发送数据,然后服务端接收数据的过程。客户端发送数据时,必须先将数据存入Buffer中,然后将Buffer中的内容写入通道。服务端这边接收数据必须通过Channel将数据读入到Buffer中,然后再从Buffer中取出数据来处理。

  在NIO中,Buffer是一个顶层父类,它是一个抽象类,常用的Buffer的子类有:

  • ByteBuffer
  • IntBuffer
  • CharBuffer
  • LongBuffer
  • DoubleBuffer
  • FloatBuffer
  • ShortBuffer

  如果是对于文件读写,上面几种Buffer都可能会用到。但是对于网络读写来说,用的最多的是ByteBuffer。

  关于Buffer的具体使用以及它的limit、posiion和capacity这几个属性的理解在下一篇文章中讲述。

四.Selector

  Selector类是NIO的核心类,Selector能够检测多个注册的通道上是否有事件发生,如果有事件发生,便获取事件然后针对每个事件进行相应的响应处理。这样一来,只是用一个单线程就可以管理多个通道,也就是管理多个连接。这样使得只有在连接真正有读写事件发生时,才会调用函数来进行读写,就大大地减少了系统开销,并且不必为每个连接都创建一个线程,不用去维护多个线程,并且避免了多线程之间的上下文切换导致的开销。

  与Selector有关的一个关键类是SelectionKey,一个SelectionKey表示一个到达的事件,这2个类构成了服务端处理业务的关键逻辑。

  关于Selector类的具体使用将在后续文章中阐述。

  参考资料:

  http://blog.csdn.net/wuxianglong/article/details/6604817

  

http://www.360doc.com/content/12/0515/11/1542811_211144310.shtml

  http://www.iteye.com/topic/834447

  http://weixiaolu.iteye.com/blog/1479656

  http://ifeve.com/overview/

 

 

 

 

分享到:
评论

相关推荐

    Xilinx公司xdma驱动下的底层读写DLL封装

    在本文中,我们将深入探讨Xilinx公司的xdma驱动下的底层读写DLL封装技术,这是针对PCI Express(PCIE)开发中的一个关键环节。Xilinx的xdma IP核是用于实现高性能PCIE接口的一种解决方案,而将底层读写操作封装成DLL...

    iocp网络底层封装

    **iocp网络底层封装** 在Windows操作系统中,I/O完成端口(I/O Completion Port,简称IOCP)是一种高效的多线程并发I/O处理机制。它允许开发者将多个异步I/O操作关联到一个单一的完成端口,从而实现线程池的高效...

    iOS底层网络实现

    本文将深入探讨iOS网络底层的实现,主要涉及BSD Socket、CFNetwork和NSStream这三个关键组件。理解并掌握这些技术,对于优化网络性能、处理复杂网络场景以及编写高效、可靠的网络代码至关重要。 首先,我们来看**...

    底层读写器协议浅析

    因此,RFID标准化组织EPCglobal在2007年推出了底层读写器协议LLRP(Low Level Reader Protocol),它为读写器和其控制器提供了标准的网络接口,极大地提高了RFID应用系统的构建效率。借助于开源的RFID中间件平台...

    c,c++高手实现xml文件读写解析底层

    在C或C++中实现XML文件的读写解析底层涉及到多个关键概念和技术,下面将详细阐述这些知识点。 1. **基础概念**: - **XML语法**:XML文档遵循一套严格的语法规则,包括元素、属性、文本内容、命名空间等。正确解析...

    高性能服务器底层网络通信模块的设计方法.pdf

    在高性能服务器的底层网络通信模块设计方面,文档中提出的设计方案在I/O完成端口的基础之上进行了封装,目标是创建一个具有高性能和可扩展性的通用网络通信模块。为了达到这样的目标,设计中采用了一些关键的系统...

    x64内存读写驱动

    描述中提到的“可过tp读写大部分tp游戏”,这里的“tp”可能指的是反作弊系统(T Punk或类似的简称),这些系统通常用于网络游戏,以防止玩家通过修改内存数据进行作弊。驱动能够绕过这样的保护机制,意味着它具有较...

    UGLZVD.rar_E语言_易语言驱动_驱动 游戏_驱动读写_驱动读写源码

    总结,易语言驱动技术是易语言在系统编程领域的重要组成部分,通过驱动读写源码的学习,我们可以更好地理解底层操作系统的工作机制,提升编程能力。同时,正确、合法地运用这些技术,可以推动游戏开发和系统优化等...

    底层网络库

    "底层网络库"主要关注的是操作系统提供的网络编程接口,这些接口允许开发者处理网络数据的传输和接收。本篇文章将详细探讨标题和描述中提到的两个关键概念:`select`和`epoll`,以及它们在网络编程中的应用。 首先...

    c++,java,php,c# 的网络字节流读写文件

    在编程领域,网络字节流读写文件是网络通信和数据传输中的常见操作。本文将深入探讨C++、Java、PHP和C#这四种语言在网络字节流读写文件方面的实现,以及它们各自的特点和差异。 首先,让我们从C++开始。C++提供了一...

    Qt linux获取cpu使用率、内存、网络收发速度、磁盘读写速度、磁盘剩余空间

    这种方法需要对底层系统有较深的理解。 5. 磁盘剩余空间: 获取磁盘剩余空间,可以使用QDir类的`space()`方法,传入`QDir::Free`作为参数,它会返回指定目录所在分区的可用空间。 在实际应用中,可以创建一个监控...

    Go-raw-能够读写设备驱动程序级别网络接口的数据

    在Go语言中,`raw`包提供了一种方式来直接操作网络接口的设备驱动程序级别数据,这使得开发者可以实现更底层的网络通信,比如抓包、协议分析或者自定义网络协议栈。本文将深入探讨如何使用Go的`raw`包进行网络编程,...

    Linux 下smi/mdio总线通信,用户态读写phy寄存器

    在Linux系统中,SMI(System Management Interface)和MDIO(Management Data Input/Output)总线是用来与PHY(Physical Layer)芯片进行通信的接口...同时,这样的实践也能帮助我们更好地理解底层网络硬件的工作原理。

    Linux网卡的读写编程

    在Linux操作系统中,网卡(网络接口卡)的读写编程是通过与内核通信来完成的,...以上就是关于Linux网卡读写编程的基本知识,通过理解和掌握这些,开发者可以编写出能够直接与网卡交互的程序,实现更底层的网络控制。

    RPC底层通讯原理

    2. WorkerGroup:处理实际的网络读写事件。WorkerGroup由多个工作线程组成,这些线程负责处理来自BossGroup的连接、读取数据、写入数据以及执行用户定义的业务逻辑。这样可以确保每个连接的读写操作不会阻塞其他连接...

    二三轨道磁卡读写程序含源码

    而.NET作为微软的跨平台开发框架,支持多种编程语言,包括C#和VB.NET,适合构建现代、网络化的应用程序。这些示例代码不仅为初学者提供了学习的范例,也为有经验的开发者提供了实操的参考。 开发者能够通过这些示例...

    API内存读写模块.zip易语言项目例子源码下载

    API是操作系统或库提供的函数集,允许程序员通过调用这些函数来执行特定的任务,如文件操作、网络通信或硬件控制。在易语言中,调用API需要正确地声明和使用API函数,通常通过“.dll”动态链接库来实现。这个项目中...

    行业分类-设备装置-一种用于在线读写安卓设备底层数据的程序及方法.zip

    本技术文档“一种用于在线读写安卓设备底层数据的程序及方法”聚焦于如何高效且安全地实现这一目标。 首先,我们要理解“底层数据”在安卓系统中的含义。底层数据通常指的是系统的内核级数据,包括硬件驱动、系统...

    数据读写操作API(源码+jar包+文档)

    在Java编程中,数据读写和IO操作是至关重要的部分,尤其在处理文件、网络通信以及数据库交互时。本资源包含的"数据读写操作API"提供了一个方便的工具集,帮助开发者避免直接操作底层的IO流,简化了数据处理过程。这...

    java的io流文件读写

    这些类在读写时会先存储一定量的数据,减少对底层物理设备的频繁访问。 4. 转换流(InputStreamReader/OutputStreamWriter):字节流与字符流之间的桥梁,用于在字节流和字符流之间转换。例如,如果要从一个字节...

Global site tag (gtag.js) - Google Analytics