`

请您先登录,才能继续操作

java nio 示例

    博客分类:
  • j2se
 
阅读更多

NIO主要原理和适用。

NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有 事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key,就会获得我们刚刚注册过的socketchannel,然后,我们从 这个Channel中读取数据,放心,包准能够读到,接着我们可以处理这些数据。

Selector内部原理实际是在做一个对所注册的channel的轮询访问,不断的轮询(目前就这一个算法),一旦轮询到一个channel有所注册的事情发生,比如数据来了,他就会站起来报告,交出一把钥匙,让我们通过这把钥匙来读取这个channel的内容。

 

jdk供的无阻塞I/O(NIO)有效解决了多线程服务器存在的线程开销问题,但在使用上略显得复杂一些。在NIO中使用多线程,主要目的已不是为了应对 每个客户端请求而分配独立的服务线程,而是通过多线程充分使用用多个CPU的处理能力和处理中的等待时间,达到提高服务能力的目的。 
    这段时间在研究NIO,写篇博客来记住学过的东西。还是从最简单的Hello World开始, 
client多线程请求server端,server接收client的名字,并返回Hello! +名字的字符格式给client。当然实际应用并不这么简单,实际可能是访问文件或者数据库获取信息返回给client。非阻塞的NIO有何神秘之处?代码:

1)server端代码

 

Java代码  收藏代码
  1. public class HelloWorldServer {    
  2.   
  3.     static int BLOCK = 1024;    
  4.     static String name = "";    
  5.     protected Selector selector;    
  6.     protected ByteBuffer clientBuffer = ByteBuffer.allocate(BLOCK);    
  7.     protected CharsetDecoder decoder;    
  8.     static CharsetEncoder encoder = Charset.forName("GB2312").newEncoder();    
  9.   
  10.     public HelloWorldServer(int port) throws IOException {    
  11.         selector = this.getSelector(port);    
  12.         Charset charset = Charset.forName("GB2312");    
  13.         decoder = charset.newDecoder();    
  14.     }    
  15.   
  16.     // 获取Selector    
  17.     protected Selector getSelector(int port) throws IOException {    
  18.         ServerSocketChannel server = ServerSocketChannel.open();    
  19.         Selector sel = Selector.open();    
  20.         server.socket().bind(new InetSocketAddress(port));    
  21.         server.configureBlocking(false);    
  22.         server.register(sel, SelectionKey.OP_ACCEPT);    
  23.         return sel;    
  24.     }    
  25.   
  26.     // 监听端口    
  27.     public void listen() {    
  28.         try {    
  29.             for (;;) {    
  30.                 selector.select();    
  31.                 Iterator iter = selector.selectedKeys().iterator();    
  32.                 while (iter.hasNext()) {    
  33.                     SelectionKey key = (SelectionKey) iter.next();    
  34.                     iter.remove();    
  35.                     process(key);    
  36.                 }    
  37.             }    
  38.         } catch (IOException e) {    
  39.             e.printStackTrace();    
  40.         }    
  41.     }    
  42.   
  43.     // 处理事件    
  44.     protected void process(SelectionKey key) throws IOException {    
  45.         if (key.isAcceptable()) { // 接收请求    
  46.             ServerSocketChannel server = (ServerSocketChannel) key.channel();    
  47.             SocketChannel channel = server.accept();    
  48.             //设置非阻塞模式    
  49.             channel.configureBlocking(false);    
  50.             channel.register(selector, SelectionKey.OP_READ);    
  51.         } else if (key.isReadable()) { // 读信息    
  52.             SocketChannel channel = (SocketChannel) key.channel();    
  53.             int count = channel.read(clientBuffer);    
  54.             if (count > 0) {    
  55.                 clientBuffer.flip();    
  56.                 CharBuffer charBuffer = decoder.decode(clientBuffer);    
  57.                 name = charBuffer.toString();    
  58.                 // System.out.println(name);    
  59.                 SelectionKey sKey = channel.register(selector,    
  60.                         SelectionKey.OP_WRITE);    
  61.                 sKey.attach(name);    
  62.             } else {    
  63.                 channel.close();    
  64.             }    
  65.   
  66.             clientBuffer.clear();    
  67.         } else if (key.isWritable()) { // 写事件    
  68.             SocketChannel channel = (SocketChannel) key.channel();    
  69.             String name = (String) key.attachment();    
  70.                 
  71.             ByteBuffer block = encoder.encode(CharBuffer    
  72.                     .wrap("Hello !" + name));    
  73.                 
  74.   
  75.             channel.write(block);    
  76.   
  77.             //channel.close();    
  78.   
  79.         }    
  80.     }    
  81.   
  82.     public static void main(String[] args) {    
  83.         int port = 8888;    
  84.         try {    
  85.             HelloWorldServer server = new HelloWorldServer(port);    
  86.             System.out.println("listening on " + port);    
  87.                 
  88.             server.listen();    
  89.                 
  90.         } catch (IOException e) {    
  91.             e.printStackTrace();    
  92.         }    
  93.     }    
  94. }   

 

2)client端代码

 

Java代码  收藏代码
  1. public class HelloWorldClient {    
  2.   
  3.     static int SIZE = 10;    
  4.     static InetSocketAddress ip = new InetSocketAddress("localhost"8888);    
  5.     static CharsetEncoder encoder = Charset.forName("GB2312").newEncoder();    
  6.   
  7.     static class Message implements Runnable {    
  8.         protected String name;    
  9.         String msg = "";    
  10.   
  11.         public Message(String index) {    
  12.             this.name = index;    
  13.         }    
  14.   
  15.         public void run() {    
  16.             try {    
  17.                 long start = System.currentTimeMillis();    
  18.                 //打开Socket通道    
  19.                 SocketChannel client = SocketChannel.open();    
  20.                 //设置为非阻塞模式    
  21.                 client.configureBlocking(false);    
  22.                 //打开选择器    
  23.                 Selector selector = Selector.open();    
  24.                 //注册连接服务端socket动作    
  25.                 client.register(selector, SelectionKey.OP_CONNECT);    
  26.                 //连接    
  27.                 client.connect(ip);    
  28.                 //分配内存    
  29.                 ByteBuffer buffer = ByteBuffer.allocate(8 * 1024);    
  30.                 int total = 0;    
  31.   
  32.                 _FOR: for (;;) {    
  33.                     selector.select();    
  34.                     Iterator iter = selector.selectedKeys().iterator();    
  35.   
  36.                     while (iter.hasNext()) {    
  37.                         SelectionKey key = (SelectionKey) iter.next();    
  38.                         iter.remove();    
  39.                         if (key.isConnectable()) {    
  40.                             SocketChannel channel = (SocketChannel) key    
  41.                                     .channel();    
  42.                             if (channel.isConnectionPending())    
  43.                                 channel.finishConnect();    
  44.                             channel    
  45.                                     .write(encoder    
  46.                                             .encode(CharBuffer.wrap(name)));    
  47.   
  48.                             channel.register(selector, SelectionKey.OP_READ);    
  49.                         } else if (key.isReadable()) {    
  50.                             SocketChannel channel = (SocketChannel) key    
  51.                                     .channel();    
  52.                             int count = channel.read(buffer);    
  53.                             if (count > 0) {    
  54.                                 total += count;    
  55.                                 buffer.flip();    
  56.   
  57.                                 while (buffer.remaining() > 0) {    
  58.                                     byte b = buffer.get();    
  59.                                     msg += (char) b;    
  60.                                         
  61.                                 }    
  62.   
  63.                                 buffer.clear();    
  64.                             } else {    
  65.                                 client.close();    
  66.                                 break _FOR;    
  67.                             }    
  68.                         }    
  69.                     }    
  70.                 }    
  71.                 double last = (System.currentTimeMillis() - start) * 1.0 / 1000;    
  72.                 System.out.println(msg + "used time :" + last + "s.");    
  73.                 msg = "";    
  74.             } catch (IOException e) {    
  75.                 e.printStackTrace();    
  76.             }    
  77.         }    
  78.     }    
  79.   
  80.     public static void main(String[] args) throws IOException {    
  81.         
  82.         String names[] = new String[SIZE];    
  83.   
  84.         for (int index = 0; index < SIZE; index++) {    
  85.             names[index] = "jeff[" + index + "]";    
  86.             new Thread(new Message(names[index])).start();    
  87.         }    
  88.         
  89.     }    
  90. }   

分享到:
评论

相关推荐

    java nio示例代码

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一个新特性,旨在提供一种比传统的IO(I/O)模型更高效、性能更好的处理输入和输出的方式。传统的Java IO基于流(Stream)...

    JAVA nio的一个简单的例子

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种I/O模型,旨在提供一种更高效、更具弹性的I/O处理方式。相比于传统的BIO( Blocking I/O)模型,NIO在处理高并发和大...

    java NIO详细教程

    #### 五、Java NIO 示例 ##### Channel和Buffer操作示例 ```java // 创建一个FileChannel FileChannel fileChannel = new FileInputStream(file).getChannel(); // 创建一个ByteBuffer ByteBuffer buffer = ...

    Java NIO测试示例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效、灵活的I/O操作方式。NIO与传统的 Blocking I/O(阻塞I/O)模式相比,...

    java nio 包读取超大数据文件

    ### Java NIO 处理超大数据文件的知识点详解 #### 一、Java NIO简介 Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本...

    java NIO原理和使用

    下面是一个简单的 Java NIO 示例,展示了如何使用 `FileChannel` 和 `ByteBuffer` 进行文件复制: ```java package nio; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio....

    java nio基础使用示例

    以上就是Java NIO的基础使用示例。通过这种方式,服务器可以高效地处理来自多个客户端的连接请求,而不需要为每个客户端创建单独的线程,降低了系统的资源消耗。值得注意的是,Java NIO的API相对复杂,使用时需要...

    一个java NIO的例子

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统I/O模型的新...通过分析和运行这个示例,开发者可以更深入地理解Java NIO的工作原理,并能更好地运用到实际项目中。

    Java.NIO资源下载资源下载

    根据提供的文件信息,我们可以提取并总结出关于Java NIO(New Input/Output)的重要知识点。 ### Java NIO 概述 Java NIO 是 Java 平台的一个重要特性,首次出现在 Java 1.4 版本中。它为 Java 开发者提供了一套...

    java nio 实现socket

    ### Java NIO 实现Socket通信详解 #### 一、NIO与传统IO的区别及优势 在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O...

    java nio 读文件

    Java NIO(New IO)是Java 1.4版本引入的一个新模块,它提供了一种不同于标准Java IO API的处理I/O操作的方式。NIO的主要特点是面向缓冲区,非阻塞I/O,以及选择器,这些特性使得NIO在处理大量并发连接时表现出更高...

    Java NIO实战开发多人聊天室

    01-Java NIO-课程简介.mp4 05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 08-Java NIO-Channel-...23-Java NIO-Selector-示例代码(客户端).mp4 24

    基于java NIO的socket通信demo

    总的来说,这个示例展示了如何使用Java NIO进行Socket通信,通过非阻塞的方式提高系统的并发处理能力。同时,它还演示了如何处理字符集问题,保证了跨平台数据交换的准确性。对于理解和实践Java NIO在网络编程中的...

    JAVA NIO学习网站

    博主还可能分享了实际示例代码,帮助读者更好地理解和掌握Java NIO。 至于`.classpath`和`.project`文件,它们是Eclipse IDE的工作空间配置文件,`.classpath`定义了项目的类路径,`.project`包含了项目设置。`bin`...

    java nio im(server+client)

    在这个Java NIO IM(即时通讯)服务器和客户端的示例中,我们将探讨如何利用NIO进行双向通信,并理解其背后的机制。 1. **NIO基础概念** - **通道(Channel)**:在NIO中,数据是通过通道进行传输的。通道类似于流...

    基于java NIO的简单聊天软件示例

    JAVA NIO有两种解释:一种叫非阻塞IO(Non-blocking I/O),另一种也叫新的IO(New I/O),其实是同一个概念。它是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为...

    JAVA-NIO-DEMO

    本示例"JAVA-NIO-DEMO"提供了关于Java NIO的实际应用,通过Anontion(注解)、Applet(小程序)和NIO的Demo,帮助开发者更深入地理解和掌握这些概念。 首先,让我们深入了解Java NIO。NIO的核心组件包括: 1. **...

    nio.rar_FastCopyFile.java_NIO_UseFloatBuffer.java_java nio_文件锁

    这个文件很可能是一个示例程序,演示了如何使用Java NIO进行高效的大文件复制。在传统的Java I/O中,我们通常使用InputStream和OutputStream进行文件复制,而这种方式需要不断读写,造成大量的上下文切换,效率较低...

Global site tag (gtag.js) - Google Analytics