java nio 学习 (参考 网上其他作者 非原创)

1) 服务端
package niotest.server;

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.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;

public class NioServer {

    public static int BLOCK = 1024;
    private Selector selector;
    private ByteBuffer clientBuffer = ByteBuffer.allocate(BLOCK);
    private CharsetDecoder decoder;
    private static String name = "";
    public static CharsetEncoder encoder = Charset.forName("GB2312").newEncoder();
    
    public NioServer(int port) throws IOException {
        selector = this.getSelector(port);
        Charset charset = Charset.forName("GB2312");
        decoder = charset.newDecoder();
        System.out.println("NioServer starting...");
    }
    
    // 获得Selector,打开监听
    private Selector getSelector(int port) throws IOException{
        // 新建nio通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 建立选择器
        Selector selector = Selector.open();
        // 新建socket端口
        serverSocketChannel.socket().bind(new InetSocketAddress(port));
        // nio通道为非阻塞
        serverSocketChannel.configureBlocking(false);
        // 将nio通道绑定到选择器
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        return selector;
    }
    
    // 监听端口
    public void listen() {
        try{
            //不断监听
            while(true){
                // 获取通道内是否有选择器关心的事件
                int cnt = this.selector.select();
                // 选择器关心的事件的集合
                Iterator iter = selector.selectedKeys().iterator();
                // 循环做处理
                while (iter.hasNext()) {
                    // 遍历每个key
                    SelectionKey key = (SelectionKey) iter.next();
                    iter.remove();
                    doProcess(key);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    // 处理事件
    private void doProcess(SelectionKey key) throws IOException {
        if(key.isAcceptable()) {
            // 接收请求
            ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
            // 得到请求
            SocketChannel socketChannel = serverSocketChannel.accept();  
            // 非阻塞模式
            socketChannel.configureBlocking(false);
            // 注册
            socketChannel.register(this.selector, SelectionKey.OP_READ);
        } else if(key.isReadable()) {
            // 读信息
            SocketChannel socketChannel = (SocketChannel) key.channel();
            int count = socketChannel.read(clientBuffer);
            if(count > 0){
                // 有内容的时候
                clientBuffer.flip();
                CharBuffer charBuffer = decoder.decode(clientBuffer);
                name = charBuffer.toString();
                SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_WRITE);
                selectionKey.attach(name);
            } else {
                
                socketChannel.close();
            }
            clientBuffer.clear();
        } else if(key.isWritable()){
            // 写事件
            SocketChannel socketChannel = (SocketChannel) key.channel();
            String name = (String) key.attachment();
            ByteBuffer block = encoder.encode(CharBuffer.wrap("Hello " + name));
            socketChannel.write(block);
            socketChannel.close(); // 该通道运行 结束
        }
    }
    
    public static void main(String args[]) {
        int port = 8888;
        try{
            NioServer nioServer = new NioServer(port);
            
            // 启动 监听
            nioServer.listen();
        }catch(Exception e){
            
            e.printStackTrace();
        }
    }
}

2) 客户端
package niotest.client;

import java.net.InetSocketAddress;

import niotest.NioMessage;

public class NioClient {

    private static int SIZE = 10;
    private static InetSocketAddress ip = new InetSocketAddress("localhost", 8888);
   
    public static void main(String args[]) {
       
        String name[] = new String[SIZE];
        for(int i = 0; i < SIZE; i++) {
            name[i] = "testMessage[" + i + "]" ;
            new Thread(new NioMessage(name[i], ip)).start();
        }
    }
}

3)客户端 消息类
package niotest;

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.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;

public class NioMessage implements Runnable {

    private String name = "";
    private String message = "";
    private InetSocketAddress ip;
    private static CharsetEncoder encoder = Charset.forName("GB2312").newEncoder();
   
    public NioMessage(String name, InetSocketAddress ip) {
        this.name = name;
        this.ip = ip;
    }
   
    @Override
    public void run() {
        try{
            // TODO Auto-generated method stub
            long start = System.currentTimeMillis();
            // 打开socket通道
            SocketChannel clientChannel = SocketChannel.open();
            // 设为非阻塞
            clientChannel.configureBlocking(false);
            // 打开选择器
            Selector selector = Selector.open();
            // 注册连接服务端
            clientChannel.register(selector, SelectionKey.OP_CONNECT);
            // 连接
            clientChannel.connect(ip);
            // 缓冲区
            ByteBuffer byteBuffer = ByteBuffer.allocate(10 * 1024);
            int total = 0;
            _FOR:while(true){
                int cnt = selector.select();
                Iterator iter = selector.selectedKeys().iterator();
               
                while(iter.hasNext()) {
                   
                    SelectionKey selectionKey = (SelectionKey) iter.next();
                    iter.remove();
                    if(selectionKey.isConnectable()){
                        // 连接
                        SocketChannel channel = (SocketChannel) selectionKey.channel();
                        if(channel.isConnectionPending()){
                            // 是否在当前进程中
                            channel.finishConnect();
                            channel.write(encoder.encode(CharBuffer.wrap(this.name)));
                            channel.register(selector, SelectionKey.OP_READ);
                        }
                    } else if(selectionKey.isReadable()){
                        // 读服务端返回来的信息
                        SocketChannel channel = (SocketChannel) selectionKey.channel();
                        int count = channel.read(byteBuffer);
                        if(count > 0) {
                            // 有内容的时候
                            total = total + count;
                            byteBuffer.flip();
                            while(byteBuffer.remaining() > 0) {
                                byte b = byteBuffer.get();
                                this.message = this.message + (char)b;
                            }
                            byteBuffer.clear();
                        } else {
                            clientChannel.close();
                            break _FOR;
                        }
                    }
                }
            }
            double lastSecond = (System.currentTimeMillis() - start);
            System.out.println(this.message + "used time :" + lastSecond + "ms.");
            this.message = "";
        } catch(Exception e){
            e.printStackTrace();
        }
    }
}
 

你可能感兴趣的:(java,职场,nio,休闲)