<返回更多

Netty 实战:如何实现文件服务器?

2020-12-25    
加入收藏

文件服务器

实现一个可以展示指定用户输入的文件路径,返回对应文件内容的服务器。

Netty 实战:如何实现文件服务器?

 

实例代码

服务端

public class FileServer {

    public static void main(String[] args) {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            ChannelFuture channelFuture = serverBootstrap.group(bossGroup, workerGroup)
                    .channel(NIOServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            // 编码 String
                            ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8))
                                    // 按照行进行解码
                                    .addLast(new LineBasedFrameDecoder(1024))
                                    // String 解码
                                    .addLast(new StringDecoder(CharsetUtil.UTF_8))
                                    // 大数据流的处理
                                    .addLast(new ChunkedWriteHandler())
                                    .addLast(new FileServerHandler());

                        }
                    })
                    .bind(8889)
                    .syncUninterruptibly();
            channelFuture.channel().closeFuture().syncUninterruptibly();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

}

FileServerHandler.JAVA

针对文件服务器的处理,实现如下:

import java.io.RandomaccessFile;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.stream.ChunkedFile;

public class FileServerHandler extends SimpleChannelInboundHandler<String> {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 提醒客户端输入文件路径
        ctx.writeAndFlush("HELLO: Type the path of the file to retrieve.n");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        // 只读方式打开文件
        try(RandomAccessFile file = new RandomAccessFile(msg, "r")) {
            long length = file.length();
            ctx.write("OK: " + length + 'n');

            ctx.write(new ChunkedFile(file));
            ctx.writeAndFlush("n");
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

整体比较简单,exceptionCaught 为异常时的处理。

channelActive() 为客户端连接时,服务端返回客户端的提示。

channelRead0() 为服务端对于客户端的反馈,就是通过客户端输入的文件路径,返回文件内容。

测试验证

我们直接使用本地的 telnet

输入 telnet localhost 8889

192:~ houbinbin$ telnet localhost 8889
Trying ::1...
Connected to localhost.
Escape character is '^]'.
HELLO: Type the path of the file to retrieve.
/Users/houbinbin/code/_github/netty-learn/netty-learn-four/src/main/java/com/github/houbb/netty/learn/four/file/FileServer.java

反馈如下:

就是把 FileServer.java 这个文件内容全部返回回来了。

OK: 2387
/*
 * Copyright (c)  2019. houbinbin Inc.
 * netty-learn All rights reserved.
 */

package com.github.houbb.netty.learn.four.file;

....... 内容省略

/**
 * <p> </p>
 *
 * <pre> Created: 2019/9/21 11:49 PM  </pre>
 * <pre> Project: netty-learn  </pre>
 *
 * @author houbinbin
 */
public class FileServer {

    public static void main(String[] args) {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        .... 内容省略
    }

}

Connection closed by foreign host.
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>