`
zhanghaj00
  • 浏览: 64090 次
社区版块
存档分类
最新评论

补基础系列 之 NIO

 
阅读更多

昨天看了hadoop代码,貌似前段时间看的NIO都忘完了。这里附上前段时间写的基于NIO的 socketServer和client的代码。并在这里多嘴几句,加深记忆:

       BIO:1.4以前 阻塞IO

       NIO:1.4-1.7 其中有基于channel的非阻塞IO 和 selector的多路复用IO

       AIO :1.7  异步IO

这上面估计就是这几种IO的区别了。。。。

还有就是这张图,,顺便附上一个连接 以后可以学习AIO:http://colobu.com/2014/11/13/java-aio-introduction/

Server端:

package com.NIO;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Logger;

/**
 * NIO服务端
 *
 * @author shirdrn
 */
public class SelectorFirst extends Thread {

    private static final Logger log = Logger.getLogger(SelectorFirst.class.getName());
    private InetSocketAddress inetSocketAddress;
    private Handler handler = new ServerHandler();

    public SelectorFirst(String hostname, int port) {
        inetSocketAddress = new InetSocketAddress(hostname, port);
    }

    @Override
    public void run() {
        try {
            Selector selector = Selector.open(); // 打开选择器
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 打开通道
            serverSocketChannel.configureBlocking(false); // 非阻塞
            serverSocketChannel.socket().bind(inetSocketAddress);
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); // 向通道注册选择器和对应事件标识
            log.info("Server: socket server started.");
            while(true) { // 轮询
                int nKeys = selector.select();
                if(nKeys>0) {
                    Set<SelectionKey> selectedKeys = selector.selectedKeys();
                    Iterator<SelectionKey> it = selectedKeys.iterator();
                    while(it.hasNext()) {
                        SelectionKey key = it.next();
                        if(key.isAcceptable()) {
                            log.info("Server: SelectionKey is acceptable.");
                            handler.handleAccept(key);
                        } else if(key.isReadable()) {
                            log.info("Server: SelectionKey is readable.");
                            handler.handleRead(key);
                        } else if(key.isWritable()) {
                            log.info("Server: SelectionKey is writable.");
                            handler.handleWrite(key);
                        }
                        it.remove();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 简单处理器接口
     *
     * @author shirdrn
     */
    interface Handler {
        /**
         * 处理{@link SelectionKey#OP_ACCEPT}事件
         * @param key
         * @throws IOException
         */
        void handleAccept(SelectionKey key) throws IOException;
        /**
         * 处理{@link SelectionKey#OP_READ}事件
         * @param key
         * @throws IOException
         */
        void handleRead(SelectionKey key) throws IOException;
        /**
         * 处理{@link SelectionKey#OP_WRITE}事件
         * @param key
         * @throws IOException
         */
        void handleWrite(SelectionKey key) throws IOException;
    }

    /**
     * 服务端事件处理实现类
     *
     * @author shirdrn
     */
    class ServerHandler implements Handler {

        @Override
        public void handleAccept(SelectionKey key) throws IOException {
            ServerSocketChannel serverSocketChannel = (ServerSocketChannel)key.channel();
            SocketChannel socketChannel = serverSocketChannel.accept();
            log.info("Server: accept client socket " + socketChannel);
            socketChannel.configureBlocking(false);
            socketChannel.register(key.selector(), SelectionKey.OP_READ);
        }

        @Override
        public void handleRead(SelectionKey key) throws IOException {
            ByteBuffer byteBuffer = ByteBuffer.allocate(5);
            SocketChannel socketChannel = (SocketChannel)key.channel();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] bytes;
            int size = 0;
            while((size =socketChannel.read(byteBuffer))>0){
                byteBuffer.flip();
                bytes = new byte[size];
                byteBuffer.get(bytes);
                log.info("Server: data = " + new String(byteBuffer.array(), 0, size));
                baos.write(bytes);
                byteBuffer.clear();
            }
            bytes = baos.toByteArray();
            ByteBuffer buffer = ByteBuffer.allocate(5);
            socketChannel.write(buffer.wrap("caonima\nshibushi".getBytes()));
            /*while(true) {
                int readBytes = socketChannel.read(byteBuffer);
                if(readBytes>0) {
                    log.info("Server: readBytes = " + readBytes);
                    log.info("Server: data = " + new String(byteBuffer.array(), 0, readBytes));
                    byteBuffer.flip();
                    socketChannel.write(byteBuffer);
                }
              //  break;
            }*/
            socketChannel.close();
        }

        @Override
        public void handleWrite(SelectionKey key) throws IOException {
            ByteBuffer byteBuffer = (ByteBuffer) key.attachment();
            byteBuffer.flip();
            SocketChannel socketChannel = (SocketChannel)key.channel();
            socketChannel.write(byteBuffer);
            if(byteBuffer.hasRemaining()) {
                key.interestOps(SelectionKey.OP_READ);
            }
            byteBuffer.compact();
        }
    }

    public static void main(String[] args) {
        SelectorFirst server = new SelectorFirst("localhost", 1000);
        server.start();
    }
}

 Client端

 

package com.NIO;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.logging.Logger;

/**
 * NIO客户端
 *
 * @author shirdrn
 */
public class Client {

    private static final Logger log = Logger.getLogger(Client.class.getName());
    private InetSocketAddress inetSocketAddress;

    public Client(String hostname, int port) {
        inetSocketAddress = new InetSocketAddress(hostname, port);
    }

    /**
     * 发送请求数据
     * @param requestData
     */
    public void send(String requestData) {
        try {
            SocketChannel socketChannel = SocketChannel.open(inetSocketAddress);
            socketChannel.configureBlocking(false);
            ByteBuffer byteBuffer = ByteBuffer.allocate(512);
            socketChannel.write(ByteBuffer.wrap(requestData.getBytes()));
            while (true) {
                byteBuffer.clear();
                int readBytes = socketChannel.read(byteBuffer);
                if (readBytes > 0) {
                    byteBuffer.flip();
                    log.info("Client: readBytes = " + readBytes);
                    log.info("Client: data = " + new String(byteBuffer.array(), 0, readBytes));
                    socketChannel.close();
                    break;
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String hostname = "localhost";
        String requestData = "Actions speak louder than words!\n" +
                " but you cant see";
        int port = 1000;
        new Client(hostname, port).send(requestData);
    }
}

 

分享到:
评论

相关推荐

    面试快餐几个图一目了然-临阵补仓.zip

    这种类型的资源通常包含一系列图表,用简洁明了的方式帮助面试者在短时间内理解和复习关键概念。 【描述】"面试快餐几个图一目了然---临阵补仓" 强调了这份资料的特点是快速学习和直观理解。"临阵补仓"这个成语暗示...

    tomcat最新版本8

    2. **NIO2接口**:Tomcat 8引入了Java NIO2 API,这使得Tomcat可以更好地利用现代操作系统提供的非阻塞I/O特性,从而提升整体性能。 3. **WebSocket支持**:Tomcat 8原生支持WebSocket协议,允许双向通信,为实时...

    tomcat包资源

    7. **安全性**:Tomcat提供了多种安全功能,如角色基础的访问控制(RBAC)、SSL/TLS支持、-form和-digest认证机制等。可以通过`conf/web.xml`和`conf/server.xml`配置安全相关的元素。 8. **性能优化**:为了提高...

    jdk1.7.0_17.rar

    JDK1.7.0_17这个具体版本,主要是在JDK7的基础上进行了一系列的维护和更新,包括但不限于安全补丁、性能优化和稳定性提升。这些更新对于保持Java应用程序的安全性和可靠性至关重要。在安装JDK1.7.0_17后,开发者可以...

    tomcat5.5安装版

    - 安装完成后,会在指定目录下生成一系列文件夹,如`bin`(包含启动和停止脚本)、`conf`(配置文件)、`webapps`(部署应用程序的地方)等。 5. **配置Tomcat**: - `server.xml`是Tomcat的主要配置文件,位于`...

    jdk6u45JDK6u45

    4. **NIO增强**:非阻塞I/O(Non-blocking I/O, NIO)在Java 6中被引入并在此版本中得到加强,允许开发者创建高并发、高性能的网络应用。 5. **Web服务支持**:JDK6u45增强了对Java API for RESTful Web Services ...

    jdk-6u45-windows-x64.rar

    这个版本在前一版的基础上进行了一系列的改进和优化,旨在提升开发者的工作效率和应用程序的性能。 首先,JDK 6u45包含了Java运行时环境(JRE),使得用户能够在Windows平台上运行基于Java的应用程序。JRE包括了...

    apache-tomcat-9.0.27.zip

    默认配置使用了基于NIO(非阻塞I/O)的连接器,但也可以切换到Bio(阻塞I/O)或Nio2。 7. **安全性**:Apache Tomcat支持SSL/TLS加密,可以在`server.xml`中配置证书和监听端口,以提供HTTPS服务。它还支持角色基础...

    tomcat8.5.9

    例如,它引入了NIO2连接器,这是一个新的网络API,提供了更好的异步处理能力。此外,还改进了JMX(Java Management Extensions)支持,使得监控和管理Tomcat实例更加便捷。 2. **安全性增强** Tomcat 8.5.9 包含了...

    jdk1.7-windows64位

    5. **文件系统API(NIO.2)**:提供了更强大的文件操作能力,包括路径操作、文件属性查询等,符合POSIX标准。 6. **改进的编译器(Javac)**:Javac的性能得到了显著提升,同时增强了错误和警告消息的清晰度。 7. ...

    jdk1.6.0_20

    这个版本在Java 6系列中扮演着关键角色,因为它包含了诸多改进、修复和新特性,以提升开发者的工作效率和程序性能。 一、JDK简介 Java Development Kit是Java编程语言的软件开发工具包,它包含了一组用于编写、编译...

    JDK-1.6u45-Windows 32位

    2. **NIO.2 (New I/O 2)**:提供了更高级别的I/O API,如Path类、Files类和Channels,使得文件操作更加简便且高效。 3. **改进的Swing组件**:JDK 1.6包含了一些Swing组件的增强,如JTabbedPane的改进,以及对...

    httpclient-4.3.1.jar httpcore-4.4.13.jar commons-logging-1.2.jar

    1. **NIO和blocking I/O模式**:支持基于Java NIO的高性能连接管理。 2. **连接管理策略**:智能地管理连接的创建、复用和关闭。 3. **低级别HTTP消息处理**:提供对HTTP头和消息体的解析和构建。 **Commons ...

    apache-tomcat-7.0.14.rar

    这个"apache-tomcat-7.0.14.rar"是一个压缩包,包含了Apache Tomcat的7.0.14版本,该版本发布于2011年,是Tomcat 7系列的一个稳定版本。下面将详细介绍Tomcat及其相关知识点。 1. **Tomcat简介**:Apache Tomcat是...

    apache-tomcat-7.0.108(UTF8).zip

    4. **连接器优化**:Tomcat 7的NIO(非阻塞I/O)和 APR(Apache Portable Runtime)连接器提供了更高的并发性能,适合处理高流量的Web应用程序。 5. **配置改进**:Tomcat 7的配置文件更加简洁,易于理解和管理。...

    jdk-7u80-windows-x64.rar

    Java Development Kit...总的来说,`jdk-7u80-windows-x64.rar`是一个为Windows 64位系统准备的JDK 7更新版本,为开发者提供了稳定、高效的Java开发环境,包含了丰富的API和强大的开发工具,是Java开发的重要基础。

    apache-tomcat-6.0.26免安装版

    它的6.0.26版本是一个较旧但仍然具有广泛使用基础的版本。这个"免安装版"意味着它是一个可直接解压并使用的版本,无需进行复杂的安装过程,方便用户在不同环境中快速部署。 1. **Tomcat架构**: Apache Tomcat基于...

    apache-tomcat-5.5.26

    - 通过调整`server.xml`中的线程池设置、开启连接器的Keep-Alive选项、使用NIO连接器等方式可以提升Tomcat的性能。 - 使用内存池和JVM调优也能改善Tomcat在高并发情况下的表现。 8. **API文档**: - 提供的API...

    jdk1.6.0_35

    总之,JDK1.6.0_35是一个重要的Java开发和运行环境,它在Java 6的基础上进行了多项改进,包括性能优化、安全性提升和API扩展,为开发者提供了稳定可靠的开发平台。虽然现在已经有了更新的JDK版本,但1.6.0_35在当时...

Global site tag (gtag.js) - Google Analytics