1、OIO与NIO代码示例比较

来源:互联网 发布:淘宝销售管理软件 编辑:程序博客网 时间:2024/06/06 06:54
  • 传统socket服务端,代码示例
package OIO;import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 传统socket服务端 *  */public class OioServer {    @SuppressWarnings("resource")    public static void main(String[] args) throws Exception {        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();        //创建socket服务,监听10101端口        ServerSocket server=new ServerSocket(10101);        System.out.println("服务器启动!");        while(true){            //获取一个套接字(阻塞)            final Socket socket = server.accept();            System.out.println("来个一个新客户端!");            newCachedThreadPool.execute(new Runnable() {                @Override                public void run() {                    //业务处理                    handler(socket);                }            });        }    }    /**     * 读取数据     * @param socket     * @throws Exception     */    public static void handler(Socket socket){            try {                byte[] bytes = new byte[1024];                InputStream inputStream = socket.getInputStream();                while(true){                    //读取数据(阻塞)                    int read = inputStream.read(bytes);                    if(read != -1){                        System.out.println(new String(bytes, 0, read));                    }else{                        break;                    }                }            } catch (Exception e) {                e.printStackTrace();            }finally{                try {                    System.out.println("socket关闭");                    socket.close();                } catch (IOException e) {                    e.printStackTrace();                }            }    }}

  • NIO服务端,代码示例
package NIO;import java.io.IOException;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;/** * NIO服务端 */public class NIOServer {    // 通道管理器    private Selector selector;    /**     * 获得一个ServerSocket通道,并对该通道做一些初始化的工作     *      * @param port     *            绑定的端口号     * @throws IOException     */    public void initServer(int port) throws IOException {        // 获得一个ServerSocket通道        ServerSocketChannel serverChannel = ServerSocketChannel.open();        // 设置通道为非阻塞        serverChannel.configureBlocking(false);        // 将该通道对应的ServerSocket绑定到port端口        serverChannel.socket().bind(new InetSocketAddress(port));        // 获得一个通道管理器        this.selector = Selector.open();        // 将通道管理器和该通道绑定,并为该通道注册SelectionKey.OP_ACCEPT事件,注册该事件后,        // 当该事件到达时,selector.select()会返回,如果该事件没到达selector.select()会一直阻塞。        serverChannel.register(selector, SelectionKey.OP_ACCEPT);    }    /**     * 采用轮询的方式监听selector上是否有需要处理的事件,如果有,则进行处理     *      * @throws IOException     */    public void listen() throws IOException {        System.out.println("服务端启动成功!");        // 轮询访问selector        while (true) {            // 当注册的事件到达时,方法返回;否则,该方法会一直阻塞            selector.select();            //selector.select(10000);            //selector.wakeup();            // 获得selector中选中的项的迭代器,选中的项为注册的事件            Iterator<?> ite = this.selector.selectedKeys().iterator();            while (ite.hasNext()) {                SelectionKey key = (SelectionKey) ite.next();                // 删除已选的key,以防重复处理                ite.remove();                handler(key);            }        }    }    /**     * 处理请求     *      * @param key     * @throws IOException     */    public void handler(SelectionKey key) throws IOException {        // 客户端请求连接事件        if (key.isAcceptable()) {            handlerAccept(key);            // 获得了可读的事件        } else if (key.isReadable()) {            handelerRead(key);        }    }    /**     * 处理连接请求     *      * @param key     * @throws IOException     */    public void handlerAccept(SelectionKey key) throws IOException {        ServerSocketChannel server = (ServerSocketChannel) key.channel();        // 获得和客户端连接的通道        SocketChannel channel = server.accept();        // 设置成非阻塞        channel.configureBlocking(false);        // 在这里可以给客户端发送信息哦        System.out.println("新的客户端连接");        // 在和客户端连接成功之后,为了可以接收到客户端的信息,需要给通道设置读的权限。        channel.register(this.selector, SelectionKey.OP_READ);    }    /**     * 处理读的事件     *      * @param key     * @throws IOException     */    public void handelerRead(SelectionKey key) throws IOException {        // 服务器可读取消息:得到事件发生的Socket通道        SocketChannel channel = (SocketChannel) key.channel();        // 创建读取的缓冲区        ByteBuffer buffer = ByteBuffer.allocate(1024);        int read = channel.read(buffer);        if(read > 0){            byte[] data = buffer.array();            String msg = new String(data).trim();            System.out.println("服务端收到信息:" + msg);            //回写数据            ByteBuffer outBuffer = ByteBuffer.wrap("好的".getBytes());            channel.write(outBuffer);// 将消息回送给客户端        }else{            System.out.println("客户端关闭");            key.cancel();        }    }    /**     * 启动服务端测试     *      * @throws IOException     */    public static void main(String[] args) throws IOException {        NIOServer server = new NIOServer();        server.initServer(8000);        server.listen();    }}
原创粉丝点击