nio示例

本文介绍了一个使用Java NIO实现的服务端文件上传示例。服务端通过非阻塞模式监听客户端连接请求,并接收客户端上传的文件,将其保存到指定文件夹中。文章详细展示了如何使用ServerSocketChannel和SocketChannel进行非阻塞通信,以及如何利用选择器Selector来高效处理多个客户端的并发请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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();
        }
    }
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值