集册 Java实例教程 基于通道选择器的回声客户端

基于通道选择器的回声客户端

欢马劈雪     最近更新时间:2020-01-02 10:19:05

433
基于通道选择器的Echo Client


import java.io.BufferedReader;

import java.io.EOFException;
/**来自 
 NowJava.com - 时  代  Java**/

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.InetAddress;

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.CharacterCodingException;

import java.nio.charset.Charset;

import java.nio.charset.CharsetDecoder;

import java.nio.charset.CharsetEncoder;/*来自 时 代 J a v a 公 众 号 - N o w J a v  a . c o m*/

import java.util.Date;

import java.util.Iterator;


public class NioEchoClient2 implements Runnable {


    private static final int PORT_NUMBER = 9111;

    private static final long TIME_OUT = 3000;


    private String mHostname;


    private Selector mSelector;


    private final ByteBuffer mReadBuffer = ByteBuffer.allocate(8192);

    private final ByteBuffer mWritBuffer = ByteBuffer.allocate(8192);


    private CharsetDecoder mDecoder;

    private CharsetEncoder mEncoder;

    private CharsetDecoder mMsDecoder;

    private InputThread mIt;

    private boolean mIsRunning;


    public NioEchoClient2(String host) {

        this.mHostname = host;


        this.mDecoder = Charset.forName("UTF-8").newDecoder();

        this.mEncoder = Charset.forName("UTF-8").newEncoder();

        this.mMsDecoder = Charset.forName("MS949").newDecoder();


    }


    SocketChannel mChannel = null;


    @Override

    public void run() {

        try {

            this.mSelector = Selector.open();

            mChannel = createSocketChannel();

            mChannel.register(mSelector, SelectionKey.OP_READ);


            mIt = new InputThread(this);

            mIt.start();


            mIsRunning = true;

        } catch (Exception e) {

            mIsRunning = false;

            e.printStackTrace();

        }


        while (mIsRunning) {

            try {

                mSelector.select(TIME_OUT);

                Iterator<SelectionKey> selectedKeys = mSelector

                        .selectedKeys().iterator();

                while (selectedKeys.hasNext()) {

                    SelectionKey key = selectedKeys.next();

                    selectedKeys.remove();

                    if (!key.isValid())

                        continue;


                    if (!key.isReadable()) {

                        continue;

                    }

                    readData(key);

                }

            } catch (EOFException e) {

                try {

                    mChannel.close();

                    mIt.shutdown();

                } catch (IOException t) {

                }

                mIsRunning = false;

            } catch (IOException e) {

                System.out.println("disconnected from server");

                e.printStackTrace();

                try {

                    mChannel.close();

                    mIt.shutdown();

                } catch (IOException t) {

                    t.printStackTrace();

                }

                mIsRunning = false;

            } finally {


            }

        }

        System.out.println("client exits");

    }


    public void sendMessage(String s) throws CharacterCodingException {

        CharBuffer cbuf = mMsDecoder.decode(ByteBuffer.wrap(s.getBytes()));

        ByteBuffer b = mEncoder.encode(cbuf);

        mWritBuffer.clear();

        mWritBuffer.put(b);

        mWritBuffer.putChar('\r');

        mWritBuffer.putChar('\n');

        mWritBuffer.flip();

        writeData();


    }

    private void writeData() {

        long nbytes = 0;

        long toWrite = mWritBuffer.remaining();

        try {

            while (nbytes != toWrite) {

                nbytes += mChannel.write(mWritBuffer);

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }


    private void readData(SelectionKey key) throws IOException {

        SocketChannel channel = (SocketChannel) key.channel();

        mReadBuffer.clear();


        long nbytes = channel.read(mReadBuffer);

        if (nbytes < 0) {

            System.out.println("disconnected from server: end-of-stream");


            channel.close();

            mIt.shutdown();

            throw new EOFException();

        }


        mReadBuffer.flip();

        String line = mDecoder.decode(mReadBuffer).toString().trim();

        mReadBuffer.clear();

        System.out.println(line);

    }


    private SocketChannel createSocketChannel() throws IOException {

        SocketChannel client = SocketChannel.open(new InetSocketAddress(

                InetAddress.getByName(mHostname), PORT_NUMBER));

        client.configureBlocking(false);

        return client;

    }


    public static void main(String[] args) {

        String host = "192.168.0.3";


        try {

            NioEchoClient2 client = new NioEchoClient2(host);

            Thread t = new Thread(client);

            t.start();

            t.join();

        } catch (InterruptedException e) {

            e.printStackTrace();

        }


    }


    static class InputThread extends Thread {


        private NioEchoClient2 mCc;

        private BufferedReader mBr;

        private boolean mRunning;


    
展开阅读全文