博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java传统IO / NIO基础知识
阅读量:4041 次
发布时间:2019-05-24

本文共 6396 字,大约阅读时间需要 21 分钟。

1.IO的基本操作

只线程情况下只能有一个客户端的连接

package xss.netty.basicio;import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;/** * java 原生的IO处理方式 * IO Server */public class IOMainServerTest {    public static void main(String[] args) throws Exception {        ServerSocket serverSocket=new ServerSocket(9999);        System.out.println("server start.......");        while (true){            // 会阻塞client的连接,只到client的消息处理完            //也就是说一次只能处理一个客户端的请求            Socket socket=serverSocket.accept();            System.out.println("new client connect");            handler(socket);        }    }    public static  void handler(Socket socket) {        try{            InputStream inputStream=socket.getInputStream();            byte[] readBytes=new byte[1024];            while(true){                int reads =inputStream.read(readBytes);//阻塞数据的读取                if(reads != -1){                    System.out.println("message ->"+new String(readBytes,0,reads));                }else{                    break;                }            }        }catch (Exception ex){            ex.printStackTrace();        }finally {            try {                System.out.println("socket closed.");                socket.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

 

可多客户端的同时连接

package xss.netty.basicio;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;/** * java 原生的IO处理方式 *  改进之一:服务端可以同时接收多个客户端的请求 * */public class IOMainServerMutliClientTest {    public static void main(String[] args) throws Exception {        ServerSocket serverSocket=new ServerSocket(9999);        System.out.println("server start.......");        ExecutorService  executors= Executors.newCachedThreadPool();        while (true){            // 会阻塞client的连接,只到client的消息处理完            //也就是说一次只能处理一个客户端的请求            final Socket socket=serverSocket.accept();            System.out.println("new client connect");            executors.execute(new Runnable() {                public void run() {                    handler(socket);                }            });        }    }    public static  void handler(Socket socket) {        try{            InputStream inputStream=socket.getInputStream();            byte[] readBytes=new byte[1024];            while(true){                int reads =inputStream.read(readBytes);//阻塞数据的读取                if(reads != -1){                    System.out.println("message ->"+new String(readBytes,0,reads));                }else{                    break;                }            }        }catch (Exception ex){            ex.printStackTrace();        }finally {            try {                System.out.println("socket closed.");                socket.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

 

2.NIO的基本操作

package xss.netty.basicio;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 NIOMainServerTest {    //通道的管理,监听客户发送的事件    private Selector selector;    public static void main(String[] args) throws  Exception{        NIOMainServerTest serverTest=new NIOMainServerTest();        serverTest.initServer(9999);        serverTest.listen();        System.out.println("main executed.");    }    /**     * 初始化ServerSocket 通道     * @param port     * @throws IOException     */    public void initServer(int port) throws IOException{        ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();        //设置为非阻塞通道        serverSocketChannel.configureBlocking(false);        //绑定端口        serverSocketChannel.socket().bind(new InetSocketAddress(port));        //        this.selector=Selector.open();        //将selector 与 通道进行绑定,并且注册ACCEPT事件        //selector会阻塞监听是否有ACCEPT事件的到达。Selector.select()        serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);        System.out.println("Server init finished with prot="+port);    }    /**     * 轮询监听selector上是否有需要处理的事件     * @throws IOException     */    public void listen() throws  IOException{        System.out.println("start listen...");        while (true){            //当注册的事件到达时,方法返回;否则,该方法会一直阻塞            selector.select();            //获得selector中选中的项的迭代器,选中的项为注册的事件            Iterator iterator=this.selector.selectedKeys().iterator();            while(iterator.hasNext()){                SelectionKey selectionKey=(SelectionKey)iterator.next();                iterator.remove();//删除已选的key,以防重复处理                //处理请求                this.handler(selectionKey);            }        }    }    /**     * 事件类型请求的处理     * @param key     * @throws IOException     */    public void handler(SelectionKey key) throws  IOException{        if(key.isAcceptable()){            //客户端的连接请求事件            handlerAccept(key);        }else  if(key.isReadable()){            //处理客户端发送的数据            handelerRead(key);        }    }    public void handlerAccept(SelectionKey key) throws IOException {        ServerSocketChannel serverSocketChannel=(ServerSocketChannel) key.channel();        //建立与客户端连接的通道        SocketChannel channel=serverSocketChannel.accept();        channel.configureBlocking(false);        //给selector 绑定客户端,并且监听客户端发送的请求。即对于服务端来说是可读取到客户端的数据        //请求        channel.register(this.selector,SelectionKey.OP_READ);        System.out.println("New Client connected");    }    public void handelerRead(SelectionKey key) throws IOException {        SocketChannel channel=(SocketChannel)key.channel();        //缓冲区的大小以实际情况来调整        ByteBuffer byteBuffer= ByteBuffer.allocate(1024);        //读取数据, -- 示例客户端最大一次性发送1024        int read=channel.read(byteBuffer);        if(read>0){            String readMsg=new String(byteBuffer.array());            System.out.println("Read message:"+readMsg);            //响应客户端            ByteBuffer outBuffer=ByteBuffer.wrap((readMsg+" is Ok").getBytes());            channel.write(outBuffer);        }else{            System.out.println("client closed.");            key.cancel();        }    }}

操作系统IO Selector 模型类似

 

 

 

 

 

 

你可能感兴趣的文章
jvm高级特性整理
查看>>
SQL查询优化
查看>>
秒杀系统
查看>>
使用Jsoup抓取页面的数据
查看>>
时间工具类
查看>>
mybatis foreach
查看>>
微信验证域名
查看>>
Java实现微信JS-SDK【一】配置篇
查看>>
java合成图片
查看>>
httpclient 4.3.2 post get的工具类
查看>>
taskExecutor使用
查看>>
微信朋友圈分享
查看>>
eclipse安装JAVA反编译插件
查看>>
ip限制
查看>>
IE6 png 透明
查看>>
列表拖动排序
查看>>
select实例,拼音检索
查看>>
Spring MVC @Transactional注解方式事务失效的解决办法
查看>>
js正则表达式限制文本框只能输入数字,小数点,英文字母
查看>>
Spring事务失效的原因
查看>>