간단한 HTTP 서버를 구현의 Netty

클라이언트가 브라우저이기 때문에, 그래서 만이 서버를 작성해야

서버 : 바인드 포트 10086

package com.jym.http;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @program: NettyPro
 * @description: 服务端,简单实现http
 * @author: jym
 * @create: 2020/02/08
 */
public class TestSever {
    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new TestSeverInitializer());

            ChannelFuture channelFuture = serverBootstrap.bind(10086).sync();

            channelFuture.addListener(new ChannelFutureListener() {
                public void operationComplete(ChannelFuture channelFuture)  {
                    if(channelFuture.isSuccess()){
                        System.out.println("监听端口 10086 成功");
                    } else {
                        System.out.println("监听端口失败");
                    }
                }
            });
            channelFuture.channel().closeFuture().sync();

        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }
}

상속 ChannelInitializer 재정의 방법으로 사용자 초기화 필요 :

package com.jym.http;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;

/**
 * @program: NettyPro
 * @description:
 * @author: jym
 * @create: 2020/02/08
 */
public class TestSeverInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        // 向管道加入处理器
        //得到管道
        ChannelPipeline pipeline = socketChannel.pipeline();
        // 加入一个netty提供的httpServer codec
        // HttpServerCodec说明
        // 1.netty提供的一个http的编--解码器
        pipeline.addLast("JymHttpSeverCodec",new HttpServerCodec());
        // 增加自定义的处理器
        pipeline.addLast("JymHttpSeverHandler",new TestHttpSeverHandler());
    }

}

브라우저가이 요청 정상적인 요청을 전송하기 때문에 사용자 정의 핸들러는, 페이지 아이콘이 별도로 처리 할

package com.jym.http;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;

/**
 * @program: NettyPro
 * @description: 处理器,SimpleChannelInboundHandler说明:
 * 1.是ChannelInboundHandlerAdapter的子类
 * 2.HttpObject 客户端和服务器端相互通讯的数据被封装成 HttpObject
 * @author: jym
 * @create: 2020/02/08
 */
public class TestHttpSeverHandler extends SimpleChannelInboundHandler<HttpObject> {

    private static byte[] bytes;

    static {
        File file = new File("D:\\壁纸\\LOL\\1.jpg");
        FileInputStream fi = null;
        try {
            long fileSize = file.length();
            if (fileSize > Integer.MAX_VALUE) {
                throw new IOException(file.getName()+"file too big... ");
            }
            fi = new FileInputStream(file);
            bytes = new byte[(int) fileSize];
            int offset = 0;
            int numRead = 0;
            while (offset < bytes.length
                    && (numRead = fi.read(bytes, offset, bytes.length - offset)) >= 0) {
                offset += numRead;
            }
            // 确保所有数据均被读取
            if (offset != bytes.length) {
                throw new IOException("Could not completely read file "
                        + file.getName());
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fi!=null){
                try {
                    fi.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 读取客户端数据
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception {
        // 判断 httpObject 是不是一个HttpRequest请求
        if(httpObject instanceof HttpRequest){
            System.out.println("msg 类型:"+ httpObject.getClass());
            System.out.println("客户端地址:"+channelHandlerContext.channel().remoteAddress());

            HttpRequest request = (HttpRequest)httpObject;
            URI uri = new URI(request.uri());
            ByteBuf content = null;
            // 处理图标
            if("/favicon.ico".equals(uri.getPath())){
                content = Unpooled.copiedBuffer(bytes);
            } else {
                // 回复信息给浏览器
                content = Unpooled.copiedBuffer("hello,我是服务器", CharsetUtil.UTF_8);
            }
            // 构造一个 httpResponse
            DefaultFullHttpResponse response =
                    new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,content);
            // 设置响应头
            response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes());

            channelHandlerContext.writeAndFlush(response);
        }
    }

}

SimpleChannelInboundHandler 설명 :
1. ChannelInboundHandlerAdapter이의 하위 클래스
데이터 2.HttpObject 클라이언트와 서버 서로 통신이 HttpObject 포장된다

테스트 결과 :

: 액세스 포트 10086 서버를 시작한 후
그림 삽입 설명 여기
제대로 아이콘 및 콘텐츠 표시

잘못 공부 시간의 부족, 너무 얕은 지식, 용서해주십시오.

세계에서 사람들이 10 종류가 있습니다, 하나의 바이너리 이해하는 것입니다, 하나는 바이너리 이해하지 않습니다.

게시 71 개 원래 기사 · 원의 찬양 (54) · 전망 420 000 +

추천

출처blog.csdn.net/weixin_43326401/article/details/104229005