NIO 客戶端與服務端通信demo

public class NioServer {
    private static final int SERVERPORT = 8080;

    public static void main(String[] args) {
        Selector selector = null;
        ServerSocketChannel server = null;
        try {
            selector = Selector.open();
            server = ServerSocketChannel.open();
            InetSocketAddress ip = new InetSocketAddress(SERVERPORT);
            server.socket().bind(ip);
            server.configureBlocking(false);
            server.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("服務器開始接受客戶端連接");

            while (true) {
                int channelNum = selector.select(1);
                if (channelNum == 0) {
                    continue;
                }
                  //  一個選擇器負責多個通過channel  ,多個channel意味着多個socket連接
                Iterator<SelectionKey> it = selector.selectedKeys().iterator();
                while (it.hasNext()) {
                    SelectionKey key = it.next();
                    it.remove();
                    if (key.isAcceptable()) {
                        ServerSocketChannel server2 = (ServerSocketChannel) key.channel();
                        SocketChannel channel = server2.accept();
                        channel.configureBlocking(false);
                        //客戶端來連接後,標記管道是可以讀或寫的,因爲服務端也要讀或寫     key.isReadable()
                        channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);


                        System.out.println("客戶端:"
                                + channel.socket().getInetAddress().getHostName() + ":"
                                + channel.socket().getPort() + " 連接上了");
                    }
//					readable
                    if (key.isReadable()) { //包含了事件的狀態信息和時間對應的通道的綁定
//						System.out.println("可讀");
                        SocketChannel channel = (SocketChannel) key.channel();
                        CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
                        ByteBuffer buffer = ByteBuffer.allocate(50);
                        try {
                            channel.read(buffer);
                        } catch (IOException e) {
//							客戶端異常斷開連接
                            System.out.println("客戶端:"
                                    + channel.socket().getInetAddress().getHostName() + ":"
                                    + channel.socket().getPort() + " 已斷開連接");
                            channel.close();
                            continue;
                        }
                        buffer.flip();
                        String msg = decoder.decode(buffer).toString();

                        if (msg.equals("退出!@#$%")) {
//							客戶端主動斷開連接
                            System.out.println("客戶端:"
                                    + channel.socket().getInetAddress().getHostName() + ":"
                                    + channel.socket().getPort() + " 已斷開連接");
                            channel.close();
                            continue;
                        }
                        System.out.println(
                                channel.socket().getInetAddress().getHostName() + ":"
                                        + channel.socket().getPort() + ":" + msg);

                        if (key.isWritable()) {
                            CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
                            try {
                                channel.write(encoder.encode(CharBuffer.wrap("server receive your message ")));
                            } catch (IOException e) {
                                // TODO: handle exception
                                System.out.println("寫入io錯誤");
                            }
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                selector.close();
                server.close();
            } catch (IOException e) {
            }
        }
    }
}


public class NioClient {

    public static void main(String[] args) {
        ClientThread client = new ClientThread();
        client.start();
        BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
        try{
            String readline;
            while((readline = sin.readLine())!=null){
                if(readline.equals("bye")){
                    client.close();
                    System.exit(0);
                }
                client.send(readline);
            }
        }catch(IOException e){
            e.printStackTrace();
        }

        try {
            Class cls = Class.forName("actions.dispatcher.nio.NioClient");
            Class partypes[] = new Class[2];
            partypes[0] = Integer.TYPE;
            partypes[1] = Integer.TYPE;
            Method meth = cls.getMethod("add", partypes);
            NioClient methobj = new NioClient();
            Object arglist[] = new Object[2];
            arglist[0] = new Integer(37);
            arglist[1] = new Integer(47);
            Object retobj = meth.invoke(methobj, arglist);
            Integer retval = (Integer) retobj;
            System.out.println(retval.intValue());
        } catch (Throwable e) {
            System.err.println(e);
        }
    }

    public int add(int a,int b){
        return a+b;
    }
}

public class ClientThread extends Thread{
    private CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
    private CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
    private Selector selector = null;
    private SocketChannel socket = null;
    private SelectionKey clientKey = null;

    public ClientThread(){
        try{
            selector = Selector.open();
            socket = SocketChannel.open();
            socket.configureBlocking(false);
            clientKey = socket.register(selector, SelectionKey.OP_CONNECT);
            InetSocketAddress ip = new InetSocketAddress("localhost",8080);
            System.out.println(socket.connect(ip));
        }catch(IOException e){
            e.printStackTrace();
        }
    }
    public void run(){
        try{
            while(true){
                int prepareIoChannelNum=selector.select(1);   //選擇準備io操作的channel
                if(prepareIoChannelNum==0){
                    continue;
                }
                Iterator<SelectionKey> it = selector.selectedKeys().iterator();
                while(it.hasNext()){
                    SelectionKey key = it.next();
                    it.remove();
                    if(key.isConnectable()){
                        SocketChannel channel = (SocketChannel)key.channel();
                        if(channel.isConnectionPending())
                            channel.finishConnect();
                        channel.register(selector, SelectionKey.OP_READ);//告訴選擇器,客戶端要對讀數據channel感興趣
                        System.out.println("連接服務器端成功!");
                    }else if(key.isReadable()){
                        SocketChannel channel = (SocketChannel)key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(50);
                        try{
                            channel.read(buffer);
                        }catch(IOException e){
                            System.out.println("與服務器:"
                                    + channel.socket().getInetAddress().getHostName() + ":"
                                    + channel.socket().getPort() + "的連接已斷開");
                            channel.close();
                            continue;//這一句是爲了讓你看到打印信息
                        }
                        buffer.flip();
                        String msg = decoder.decode(buffer).toString();
                        System.out.println(
                                channel.socket().getInetAddress().getHostName() + ":"
                                        + channel.socket().getPort() + ":" + msg);
                    }
                }
            }

        }catch(IOException e){
            e.printStackTrace();
        }
        finally{
            try{
                selector.close();
                socket.close();
            }catch(IOException e){}
        }
    }

    public void send(String msg){
        try{
            SocketChannel client = (SocketChannel)clientKey.channel();
            client.write(encoder.encode(CharBuffer.wrap(msg)));
        }catch(Exception e){
            System.out.println("發送信息失敗");
            e.printStackTrace();
        }
    }

    public void close(){
        try{
            selector.close();
            socket.close();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}


發佈了89 篇原創文章 · 獲贊 13 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章