欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

nio示例

程序员文章站 2022-04-24 10:29:58
...

public class NioService {

private Selector selector;

public void init{
    try {
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);//开启非阻塞模式
        ssc.socket().bind(new InetSocketAddress(8082));//绑定监听端口
        selector = Selector.open();
        ssc.register(selector, SelectionKey.OP_ACCEPT);//注册选择器
        Handler handler = new Handler();
        while (true){
            if(selector.select(3000)==0){//使用超时方式完成非阻塞操作
                System.out.println("等待请求超时。。。。。。。。。");
                continue;
            }
            Iterator<SelectionKey> it = selector.selectedKeys().iterator();
            while (it.hasNext()){
                try {
                    SelectionKey sk = it.next();
                    if (sk.isAcceptable()) {//接收就绪
                        handler.handAccept(sk);
                    }
                    if (sk.isReadable()) {//读就绪
                        handler.handRead(sk);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    it.remove();//一定要手动去除完成的selectionKey,否则selector会一直保持它
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private class Handler{
    //在接收准备好后,给准备好的SocketChannel注册读就绪选择器
    public void handAccept(SelectionKey key) throws IOException {
        SocketChannel socketChannel = ((ServerSocketChannel) key.channel()).accept();
        socketChannel.configureBlocking(false);//非阻塞
        socketChannel.register(selector,SelectionKey.OP_READ);
    }

//将上传的文件转存到本地文件夹
    public void handRead(SelectionKey key) throws IOException {
        SocketChannel socketChannel = null;
        FileChannel fileChannel = null;
        try {
            socketChannel = ((SocketChannel) key.channel());
            //准备ByteBuffer
            ByteBuffer byteBuffer = ByteBuffer.allocate(128);
            byteBuffer.clear();
            //准备目标channel
            File file = new File("file/");
            if(!file.exists()){
                file.mkdirs();
            }
            fileChannel = new FileOutputStream("file/"+UUID.randomUUID().toString()).getChannel();
            //转存
            while (socketChannel.read(byteBuffer) != -1) {
                byteBuffer.flip();
                fileChannel.write(byteBuffer);
                byteBuffer.clear();//一定要clear()
            }
            //下面不确定正确性
            byteBuffer.clear();
            String sendString = "ok";
            byteBuffer.put(sendString.getBytes("utf-8"));
            socketChannel.write(byteBuffer);
        }catch (IOException e){
            throw e;
        }finally {
            if(fileChannel!=null)
                fileChannel.close();
            if(socketChannel!=null)
                socketChannel.close();
        }
    }
}

}