netty

原创
2020/05/26 21:02
阅读数 547

最近在学习netty练习下,先附上写的代码吧

注意不要使用5.0的版本了,官方直接废弃了,可以自己搜索下。因此只用4版本的。

<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.50.Final</version>
</dependency>

服务端的代码实现:

private static int port = 8080;

public static void main(String[] args) {
    // boss线程池负责接受请求
    NioEventLoopGroup bossGroup = new NioEventLoopGroup();
    // work线程池负责处理请求
    NioEventLoopGroup workGroup = new NioEventLoopGroup();
    // 创建ServerBootstrap
    ServerBootstrap serverBootstrap = new ServerBootstrap();
    // NioServerSocketChannel标记当前是服务器
    serverBootstrap.group(bossGroup, workGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
        @Override
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            // 处理每个请求hanlder
            socketChannel.pipeline().addLast(new ServerHandler());
        }
    });
    // 绑定我们的端口号码
    try {
        // 绑定端口号,同步等待成功
        ChannelFuture future = serverBootstrap.bind(port).sync();
        System.out.println("服务器启动成功:" + port);
        // 等待服务器监听端口
        future.channel().closeFuture().sync();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 优雅的关闭连接
        bossGroup.shutdownGracefully();
        workGroup.shutdownGracefully();
    }
}

ServerHandler类的实现

public class ServerHandler extends SimpleChannelInboundHandler {
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
        // 接受我们的数据
        ByteBuf byteBuf = (ByteBuf) o;
        String request = byteBuf.toString(CharsetUtil.UTF_8);
        System.out.println("接受到的客户端消息:" + request);
        // 响应内容:
        channelHandlerContext.writeAndFlush(Unpooled.copiedBuffer("这是服务端响应的消息", CharsetUtil.UTF_8));
    }
}

 

接下来开始写客户端的实现代码:

public static void main(String[] args) {
    //创建nioEventLoopGroup
    NioEventLoopGroup group = new NioEventLoopGroup();
    Bootstrap bootstrap = new Bootstrap();
    bootstrap.group(group).channel(NioSocketChannel.class).remoteAddress(new InetSocketAddress("127.0.0.1", 8080)).handler(new ChannelInitializer<SocketChannel>() {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(new ClientHandler());
        }
    });
    try {
        // 发起同步连接
        ChannelFuture sync = bootstrap.connect().sync();
        sync.channel().closeFuture().sync();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        group.shutdownGracefully();
    }
}

ClientHandler类的实现

public class ClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    // 活跃通道可以发送消息
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 发送数据
        ctx.writeAndFlush(Unpooled.copiedBuffer("活跃通道发生消息?", CharsetUtil.UTF_8));
    }
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
        System.out.println("接收服务端响应的信息:" + byteBuf.toString(CharsetUtil.UTF_8));
    }
}

然后就可以运行起来看效果了。

 

粘包和拆包的问题可以通过利用编码器LineBaseDFrameDecoder解决。在服务端的和客户端分别添加如下代码。

// 设置我们分割最大长度为1024
socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024));
// 获取数据的结果为string类型
socketChannel.pipeline().addLast(new StringEncoder());

同时发送的消息加上一个\n字符进行区分。

 

 

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部