`

【练习代码】写了基于java nio的RepeatServer -- by auzll

 
阅读更多

        昨天在翻看mina源码时,突然想起我貌似还没直接写过基于java nio的代码,于是今天想抓紧练习下,写段小程序。

 

        这段小程序可以在terminal用telnet连服务器端,输入内容,当服务器收到内容之后,会在控制台打印输出,接着再把这些内容稍做“包装”并返回给客户端terminal。程序里面还支持是否强制使用java epoll (配置个系统参数 java.nio.channels.spi.SelectorProvider = sun.nio.ch.EPollSelectorProvider就可以了),不过当然这得看运行环境了,对linux版本和java版本都有要求。下面直接贴贴代码:

 

package niotest;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;

/**
 * 基于java nio的RepeatServer。
 * 可以在terminal用telnet连服务器端,输入内容,当服务器收到内容之后,会在控制台打
 * 印输出,接着再把这些内容稍做“包装”并返回给客户端terminal。
 * 
 * @author auzll
 */
public final class RepeatServer {
    private ServerSocketChannel serverSocketChannel;
    private Selector selector;
    
    private static final String SELECTOR_PROVIDER_KEY = "java.nio.channels.spi.SelectorProvider";
    private static final String EPOLL_SELECTOR_CLASS = "sun.nio.ch.EPollSelectorProvider";
    
    public RepeatServer(boolean epoll, int port) throws IOException {
        if (epoll) {
            // 强制设置使用java epoll,需要linux和java版本的支持
            // 在我写这个测试代码的时候,我的机器环境是默认使用了EPollSelectorProvider
            System.setProperty(SELECTOR_PROVIDER_KEY, EPOLL_SELECTOR_CLASS);
        }
        
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.socket().setReuseAddress(true);
        serverSocketChannel.bind(new InetSocketAddress(port)); 
        
        selector = Selector.open();
        
        // 仅注册OP_ACCEPT
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        
        System.out.println(String.format("*** Server start on %d , selector provider class is %s ***", 
                port, selector.provider().getClass().getName()));
    }
    
    /**
     * 处理客户端连接,并注册读事件
     */
    private void handleAcceptable(SelectionKey readyKey) throws IOException {
        ServerSocketChannel serverSocketChannel = (ServerSocketChannel) readyKey.channel();
        
        SocketChannel socketChannel = serverSocketChannel.accept();
        socketChannel.configureBlocking(false);
        
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        socketChannel.register(selector, 
                SelectionKey.OP_READ, 
                byteBuffer);
    }
    
    /**
     * 处理读事件
     */
    private void handleReadable(SelectionKey readyKey) throws IOException {
        SocketChannel socketChannel = (SocketChannel) readyKey.channel();
        
        ByteBuffer readBuff = ByteBuffer.allocate(1024);
        Charset charset = Charset.defaultCharset();
        boolean gotData = false;
        
        while ( socketChannel.read(readBuff) > 0 ) {
            gotData = true;
            
            // 注册写事件
            readyKey.interestOps(readyKey.interestOps() | SelectionKey.OP_WRITE);
            
            readBuff.flip();
            CharBuffer charBuffer = charset.decode(readBuff);
            
            String repeatData = "We got: [" + charBuffer.toString().trim() + "]\r\n";
            System.out.println(repeatData);
            
            ByteBuffer attachBuff = (ByteBuffer) readyKey.attachment();
            attachBuff.clear();
            attachBuff.put(charset.encode(repeatData));
        }
        
        if (!gotData) {
            // 完全读不到数据的情况下,取消注册读事件
            readyKey.interestOps(readyKey.interestOps() & ~SelectionKey.OP_READ);
        }
    }
    
    /**
     * 处理写事件
     */
    private void handleWriteable(SelectionKey readyKey) throws IOException {
        SocketChannel socketChannel = (SocketChannel) readyKey.channel();
        
        ByteBuffer attachBuff = (ByteBuffer) readyKey.attachment();
        attachBuff.flip();
        socketChannel.write(attachBuff);
        
        // 取消注册写事件
        readyKey.interestOps(readyKey.interestOps() & ~SelectionKey.OP_WRITE);
    }
    
    /**
     * 开始服务
     */
    public void start() throws IOException {
        int selected = 0;
        while ((selected = selector.select()) > 0) {
            System.out.println("selected is " + selected);
            
            Iterator<SelectionKey> readyKeys = selector.selectedKeys().iterator();
            while (readyKeys.hasNext()) {
                
                SelectionKey readyKey = readyKeys.next();
                readyKeys.remove();
                
                if (!readyKey.isValid()) {
                    continue;
                }
                
                if (readyKey.isAcceptable()) {
                    handleAcceptable(readyKey);
                }
                
                if (readyKey.isReadable()) {
                    handleReadable(readyKey);
                }
                
                if (readyKey.isWritable()) {
                    handleWriteable(readyKey);
                }
            }
        }
    }
    
    public static void main(String[] args) throws Exception {
        // 开始测试
        new RepeatServer(false, 9876).start();
    }
}

  

        发布在 http://auzll.iteye.com

分享到:
评论

相关推荐

    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视频教程

    01-Java NIO-课程简介.mp4 02-Java NIO-概述.mp4 03-Java NIO-Channel-概述.mp4 04-Java NIO-Channel-FileChannel(介绍和示例).mp4 05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel...

    [第9节] Java NIO流-选择器操作4

    [第9节] Java NIO流-选择器操作4[第9节] Java NIO流-选择器操作4[第9节] Java NIO流-选择器操作4

    基于Java NIO实现五子棋游戏.zip

    基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现...

    基于java的开发源码-NIO网络框架 xSocket.zip

    基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络...

    Java NIO 指南 - v1.0.pdf

    Java NIO(New IO)是一个可以替代标准 Java IO API 的 IO API(从 Java 1.4 开始),Java NIO 提供了与标准 IO 不同的 IO 工作方式。本教程讲解了 Java NIO 的三个核心组件,并介绍了跟核心组件相关的内容,旨在帮助 ...

    Java-NIO-Programming-Cookbook(含源码)

    Java-NIO-Programming-Cookbook英文版和配套源代码。有一个使用DirectByteBuffer和Non-Direct Buffer文件读取速度的对比实验程序和测试结果。

    Java-NIO-Netty框架学习

    Java-NIO-Netty框架入门学习。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

    httpcore-nio-4.4.6-API文档-中文版.zip

    赠送源代码:httpcore-nio-4.4.6-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.6-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.apache.httpcomponents,artifactId:httpcore-nio,...

    httpcore-nio-4.4.15-API文档-中文版.zip

    赠送源代码:httpcore-nio-4.4.15-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.15-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.apache.httpcomponents,artifactId:httpcore-nio,...

    java基于NIO实现Reactor模型源码.zip

    java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现...

    httpcore-nio-4.4.10-API文档-中文版.zip

    赠送源代码:httpcore-nio-4.4.10-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.10.pom; 包含翻译后的API文档:httpcore-nio-4.4.10-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache....

    httpcore-nio-4.4.10-API文档-中英对照版.zip

    赠送源代码:httpcore-nio-4.4.10-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.10.pom; 包含翻译后的API文档:httpcore-nio-4.4.10-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....

    httpcore-nio-4.4.15-API文档-中英对照版.zip

    赠送源代码:httpcore-nio-4.4.15-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.15-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven信息:groupId:org.apache.httpcomponents,artifactId:...

    Java应用服务器Java-Nio-Services.zip

    JAVA服务器基于JAVA NIO I. 实现HTTP协议 II. 实现HTTPS协议 III. 实现FASTCGI协议(Client端) 运行HTTP/HTTPS服务器 运行开发包下jar文件 java -jar http-server-version-{version}.jar   ...

    基于Java的源码-NIO网络框架 xSocket.zip

    基于Java的源码-NIO网络框架 xSocket.zip

    Java视频教程 Java游戏服务器端开发 Netty NIO AIO Mina视频教程

    三、Java语言基础教程-Java NIO流篇 [第1节] Java NIO流-简介和概述.flv [第2节] Java NIO流-缓冲区.flv [第3节] Java NIO流-缓冲区操作.flv [第4节] JavaNIO流-通道1.flv [第5节] Java NIO流-通道2.flv [第6...

    httpcore-nio-4.4.5-API文档-中文版.zip

    赠送源代码:httpcore-nio-4.4.5-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.5.pom; 包含翻译后的API文档:httpcore-nio-4.4.5-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache....

    JAVA-NIO-DEMO

    Anontion、Applet、NIO等Demo,可以辅助理解一下相关知识点

    xnio-nio-3.8.4.Final-API文档-中英对照版.zip

    赠送源代码:xnio-nio-3.8.4.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.4.Final.pom; 包含翻译后的API文档:xnio-nio-3.8.4.Final-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....

Global site tag (gtag.js) - Google Analytics