1. 程式人生 > 其它 >Netty實現FTP伺服器(少點兒羅嗦,多點兒乾貨)

Netty實現FTP伺服器(少點兒羅嗦,多點兒乾貨)

目錄

引入依賴

``

<dependency>
   <groupId>io.netty</groupId>
   <artifactId>netty-codec-http</artifactId>
   <version>4.1.45.Final</version>
</dependency>

服務端程式碼

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;

/**
 * @author FanJiangFeng
 * @createTime 2021年12月12日 15:33:00
 *
 * FTP伺服器啟動類
 */
public class HttpServerDemo {

    public static void main(String[] args) throws Exception {
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        ChannelFuture channelFuture = serverBootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer() {
                    protected void initChannel(Channel channel) throws Exception {
                        ChannelPipeline pipeline = channel.pipeline();
                        pipeline.addLast(new HttpServerCodec());
                        pipeline.addLast(new HttpObjectAggregator(1024));
                        pipeline.addLast(new HttpServletRequest());
                    }
                }).bind(8888);

        channelFuture.sync();
        System.out.println("FTP伺服器啟動成功");
    }
}

處理器程式碼

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import java.io.*;
import java.net.URLDecoder;

/**
 * @author FanJiangFeng
 * @createTime 2021年12月12日 15:42:00
 */
public class HttpServletRequest extends SimpleChannelInboundHandler<FullHttpRequest> {
    //資料夾路徑
    private static String FILE_PATH = "D:\\工作\\表單電子化";
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) throws Exception {
        //獲取使用者的uri
        String uri = fullHttpRequest.uri();
        //請求方式
        String name = fullHttpRequest.method().name();
        if(!"GET".equals(name)){
            responseError("只支援GET請求",channelHandlerContext);
            return;
        }
        File file = new File(FILE_PATH + URLDecoder.decode(uri, "UTF-8"));
        if (!file.exists()) {
            responseError("檔案不存在。。。", channelHandlerContext);
            return;
        }
        if (file.isFile()) {
            // 如果是一個檔案,就執行下載
            responseFileCopy(file, channelHandlerContext);
        } else {
            // 如果是一個目錄就顯示子目錄
            responseDir(channelHandlerContext, file, uri);
        }
    }

    /**
     * 響應目錄資訊
     */
    private void responseDir(ChannelHandlerContext channelHandlerContext, File file, String uri) {
        StringBuffer buffer = new StringBuffer();
        // 獲取目錄的子檔案
        File[] files = file.listFiles();
        for (File file1 : files) {
            if ("/".equals(uri)) {
                buffer.append("<li><a href= '" + uri + file1.getName() + "'>" + file1.getName() + "</a></li>");
            } else {
                buffer.append("<li><a href= '" + uri + File.separator + file1.getName() + "'>" + file1.getName() + "</a></li>");
            }
        }
        responseClient(buffer.toString(), channelHandlerContext);
    }

    /**
     * 檔案下載
     * @param file
     * @param channelHandlerContext
     */
    private void responseFileCopy(File file, ChannelHandlerContext channelHandlerContext) {
        FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        response.headers().add("Context-type", "application/octet-stream");
        response.headers().add("Content-Length", file.length());

        Channel channel = channelHandlerContext.channel();

        FileInputStream ips = null;
        try {
            ips = new FileInputStream(file);
            byte[] by = new byte[1024];
            int read = -1;
            while ((read = ips.read(by, 0, by.length)) != -1) {
                response.content().writeBytes(by, 0, read);
            }
            channel.writeAndFlush(response);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ips != null) {
                try {
                    ips.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 響應客戶端
     */
    public void responseClient(String text,ChannelHandlerContext channelHandlerContext){
        DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        //設定響應頭
        response.headers().add("Context-type","text/html;charset=UTF-8");
        String msg = "<html><meta charset=\"UTF-8\" />" + text + "</html>";
        try {
            response.content().writeBytes(msg.getBytes("UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        channelHandlerContext.channel().writeAndFlush(response);
    }

    /**
     * 響應錯誤資訊
     */
    public void responseError(String text, ChannelHandlerContext channelHandlerContext) {
        String msg = "<h1>" + text + "</h1>";
        responseClient(msg, channelHandlerContext);
    }
}

效果圖

作者:樊同學 出處:http://www.cnblogs.com/shwee/

-------------------------------------------

個性簽名:獨學而無友,則孤陋而寡聞。做一個靈魂有趣的人!

如果覺得這篇文章對你有小小的幫助的話,記得在右下角點個“推薦”哦,博主在此感謝!

萬水千山總是情,打賞一分行不行,所以如果你心情還比較高興,也是可以掃碼打賞博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!