读书人

java学习NIO篇二

发布时间: 2012-12-20 09:53:21 作者: rapoo

java学习——NIO篇2

在前面写的nio学习中是采取的简单的demo,后来在网上看到一个demo,一个用来多线程下载的demo,在这个demo里才会体现nio的高性能之处。充分体现nio的优势。

场景:一个服务端,然后100个客户端同时连接服务端,然后下载一个文件下来。服务端只需要一个连接来处理这些来自客户端的连接。其中对文件的传递采用的是nio中的FileChannel?。很好用的一个东西。

?

忘记从哪里转过来的代码了。。。

?


服务端:

import java.io.FileInputStream;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.channels.FileChannel;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.util.Iterator;public class NIOServer {    static int BLOCK = 4096;    // 处理与客户端的交互    public class HandleClient {        protected FileChannel channel;        protected ByteBuffer buffer;        public HandleClient() throws IOException {            this.channel = new FileInputStream(filename).getChannel();            this.buffer = ByteBuffer.allocate(BLOCK);        }        public ByteBuffer readBlock() {            try {                buffer.clear();                int count = channel.read(buffer);                buffer.flip();                if (count <= 0)                    return null;            } catch (IOException e) {                e.printStackTrace();            }            return buffer;        }        public void close() {            try {                channel.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    protected Selector selector;    protected String filename = "d:\\test.jpg"; // a big file    protected ByteBuffer clientBuffer = ByteBuffer.allocate(BLOCK);    protected CharsetDecoder decoder;    public NIOServer(int port) throws IOException {        selector = this.getSelector(port);        Charset charset = Charset.forName("GB2312");        decoder = charset.newDecoder();    }    // 获取Selector    protected Selector getSelector(int port) throws IOException {        ServerSocketChannel server = ServerSocketChannel.open();        Selector sel = Selector.open();        server.socket().bind(new InetSocketAddress(port));        server.configureBlocking(false);        server.register(sel, SelectionKey.OP_ACCEPT);        return sel;    }    // 监听端口    public void listen() {        try {            for (;;) {                selector.select();                Iterator iter = selector.selectedKeys().iterator();                while (iter.hasNext()) {                    SelectionKey key = (SelectionKey) iter.next();                    iter.remove();                    handleKey(key);                }            }        } catch (IOException e) {            e.printStackTrace();        }    }    // 处理事件    protected void handleKey(SelectionKey key) throws IOException {        if (key.isAcceptable()) { // 接收请求            ServerSocketChannel server = (ServerSocketChannel) key.channel();            SocketChannel channel = server.accept();            channel.configureBlocking(false);            channel.register(selector, SelectionKey.OP_READ);        } else if (key.isReadable()) { // 读信息            System.out.println("能读");            SocketChannel channel = (SocketChannel) key.channel();            int count = channel.read(clientBuffer);            if (count > 0) {                clientBuffer.flip();                CharBuffer charBuffer = decoder.decode(clientBuffer);                System.out.println("Client >>" + charBuffer.toString());                SelectionKey wKey = channel.register(selector, SelectionKey.OP_WRITE);                wKey.attach(new HandleClient());            } else                channel.close();            clientBuffer.clear();        } else if (key.isWritable()) { // 写事件            System.out.println("能写");            SocketChannel channel = (SocketChannel) key.channel();            HandleClient handle = (HandleClient) key.attachment();            ByteBuffer block = handle.readBlock();            if (block != null)                channel.write(block);            else {                handle.close();                channel.close();            }        }    }    public static void main(String[] args) {        int port = 12345;        try {            NIOServer server = new NIOServer(port);            System.out.println("Listernint on " + port);            while (true) {                server.listen();            }        } catch (IOException e) {            e.printStackTrace();        }    }}

?客户端:

import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.channels.FileChannel;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;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class NIOClient {    static int SIZE = 10;    static InetSocketAddress ip = new InetSocketAddress("localhost", 12345);    static CharsetEncoder encoder = Charset.forName("GB2312").newEncoder();    static FileChannel[] filechannel = new FileChannel[SIZE];    static class Download implements Runnable {        protected int index;        public Download(int index) {            this.index = index;        }        public void run() {            try {                long start = System.currentTimeMillis();                SocketChannel client = SocketChannel.open();                client.configureBlocking(false);                Selector selector = Selector.open();                client.register(selector, SelectionKey.OP_CONNECT);                client.connect(ip);                ByteBuffer buffer = ByteBuffer.allocate(8 * 1024);                int total = 0;                boolean flag = true;                while (flag) {                    selector.select();                    Iterator iter = selector.selectedKeys().iterator();                    while (iter.hasNext()) {                        SelectionKey key = iter.next();                        iter.remove();                        if (key.isConnectable()) {                            SocketChannel channel = (SocketChannel) key.channel();                            if (channel.isConnectionPending())                                channel.finishConnect();                            channel.write(encoder.encode(CharBuffer.wrap("Hello from " + index)));                            channel.register(selector, SelectionKey.OP_READ);                        } else if (key.isReadable()) {                            SocketChannel channel = (SocketChannel) key.channel();                            int count = channel.read(buffer);                            if (count > 0) {                                writeToFile(buffer, index);                                total += count;                                buffer.clear();                            } else {                                filechannel[index].close();                                client.close();                                flag = false;                            }                        }                    }                }                double last = (System.currentTimeMillis() - start) * 1.0 / 1000;                System.out.println("Thread " + index + " downloaded " + total + "bytes in " + last + "s.");            } catch (IOException e) {                e.printStackTrace();            }        }    }    public static synchronized void writeToFile(ByteBuffer bb, int index) {        try {            if (filechannel[index] == null) {                filechannel[index] = new FileOutputStream(new File("test" + index + ".jpg")).getChannel();            }            bb.flip();            filechannel[index].write(bb);        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public static void main(String[] args) throws IOException {        ExecutorService exec = Executors.newFixedThreadPool(SIZE);        for (int index = 0; index < SIZE; index++) {            exec.execute(new Download(index));        }        exec.shutdown();    }}
?

读书人网 >编程

热点推荐