JAVA NIO 基礎學習

cyjjkz1 8年前發布 | 1K 次閱讀 Java

服務端 監聽    

package com.hrd.netty.demo.jnio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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;

/**
 * Created by hurd on 2016/1/26.
 */
public class NioServerListener extends Thread {

    protected Selector selector;
    protected SocketChannel socketChannel;

    public NioServerListener(Selector selector){
        this.selector = selector;
    }

    @Override
    public void run(){

        try {
            //while循環監聽事件
            while(true){
                //阻塞
                selector.select();
                //獲取選擇器中已經就緒的SelectionKey集合
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                //遍歷
                while (iterator.hasNext()){
                    SelectionKey key = iterator.next();
                    //刪除
                    iterator.remove();
                    //接受連接就緒事件
                    if(key.isAcceptable()){
                        ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                        socketChannel = ssc.accept();
                        //套接字通道設置為非阻塞模式
                        socketChannel.configureBlocking(false);
                        //向socket通道 注冊讀就緒事件
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    }else if(key.isReadable()){
                        //SocketChannel socketChannel = (SocketChannel) key.channel();
                        ByteBuffer byteBuffer = ByteBuffer.allocate(100);
                        int len = socketChannel.read(byteBuffer);
                         /*StringBuffer  dataBuffer= new StringBuffer();
                        while( -1 != len){
                            //將寫模式變為讀模式
                            byteBuffer.flip();
                            CharBuffer charBuffer = byteBuffer.asCharBuffer();
                            dataBuffer.append(charBuffer.array());
                            byteBuffer.clear();
                            len = socketChannel.read(byteBuffer);
                        }*/
                        byteBuffer.flip();
                        //讀取完畢
                        if(byteBuffer.limit()>0){
                            System.out.println("來自服務端消息:" + new String(byteBuffer.array()).trim());
                        }
                    }else if(key.isWritable()){
                        //暫時還沒想明白這個寫就緒事件干嘛用的。。。
                        System.out.println("暫不處理");
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) throws IOException {

        //打開一個 ServerSocketChannel實例 并設置為false
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        //綁定ip +端口
        serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1",1024));
        //打開一個選擇器
        Selector selector = Selector.open();
        //向 serverSocketChannel 注冊 接收就緒事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        //開啟線程進行監聽
        NioServerListener listener = new NioServerListener (selector);
        listener.start();
        //進行控制太輸入 寫事件 進行通訊
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        while(true){
            //java IO 阻塞讀取數據
            String data = bufferedReader.readLine();
            if("exit".equals(data)){
                if(null != listener.socketChannel){
                    listener.socketChannel.close();
                }
                System.out.println("主線程關閉.....");
                System.exit(0);
            }
            ByteBuffer buffer = ByteBuffer.wrap(data.getBytes());
            listener.socketChannel.write(buffer);
        }
    }
}

客戶端 監聽    

package com.hrd.netty.demo.jnio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * Created by hurd on 2016/1/26.
 */
public class NioClientListener extends Thread {

    public Selector selector;
    public SocketChannel socketChannel;

    public NioClientListener(Selector selector){
        this.selector = selector;
    }

    @Override
    public void run(){

        try {
            //while循環監聽事件
            while(true){
                //阻塞
                selector.select();
                //獲取選擇器中已經就緒的SelectionKey集合
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                //遍歷
                while (iterator.hasNext()){
                    SelectionKey key = iterator.next();
                    //刪除
                    iterator.remove();
                    socketChannel = (SocketChannel) key.channel();
                    //套接字通道設置為非阻塞模式
                    socketChannel.configureBlocking(false);

                    //連接就緒事件
                    if(key.isConnectable()){
                        socketChannel = (SocketChannel) key.channel();
                        //判斷連接是否完成
                        int i =0;
                        while(! socketChannel.finishConnect()){
                            if(++i>10){
                                throw  new RuntimeException("socket連接超時");
                            }
                            System.out.println("sock連接未完成,等待中....");
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        //向socket通道 注冊讀就緒事件
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    }else if(key.isReadable()){
                        //SocketChannel socketChannel = (SocketChannel) key.channel();
                        ByteBuffer byteBuffer = ByteBuffer.allocate(100);
                        int len = socketChannel.read(byteBuffer);
                        /*StringBuffer  dataBuffer= new StringBuffer();
                        while( -1 != len){
                            //將寫模式變為讀模式
                            byteBuffer.flip();
                            CharBuffer charBuffer = byteBuffer.asCharBuffer();
                            dataBuffer.append(charBuffer.array());
                            byteBuffer.clear();
                            len = socketChannel.read(byteBuffer);
                        }*/
                        byteBuffer.flip();
                        //讀取完畢
                        if(byteBuffer.limit()>0){
                            System.out.println("來自服務端消息:" + new String(byteBuffer.array()).trim());
                        }
                    }else if(key.isWritable()){
                        //暫時還沒想明白這個寫就緒事件干嘛用的。。。
                        System.out.println("暫不處理");
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {

        //打開一個SocketChannel實例 并設置為false
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false);
        //綁定ip +端口
        socketChannel.connect(new InetSocketAddress("127.0.0.1",1024));
        //打開一個選擇器
        Selector selector = Selector.open();
        //向 serverSocketChannel 注冊 連接就緒事件
        socketChannel.register(selector, SelectionKey.OP_CONNECT);
        //開啟線程進行監聽
        NioClientListener listener = new NioClientListener (selector);
        listener.start();
        //進行控制太輸入 寫事件 進行通訊
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        while(true){
            //java IO 阻塞讀取數據
            String data = bufferedReader.readLine();
            if("exit".equals(data)){
                socketChannel.close();
                System.out.println("主線程關閉.....");
                System.exit(0);
            }
            ByteBuffer buffer = ByteBuffer.wrap(data.getBytes());
            socketChannel.write(buffer);
        }
    }
}
 本文由用戶 cyjjkz1 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!