Netty通信的一个小Demo(客户端和服务端收发消息)

我其他文章有简单的介绍netty流程,这边就不叙述了,直接贴代码了:
(1)NettyServer——服务端:

 public static void main(String[] args) throws InterruptedException {
        NettyServerDemo.start();
    }

    public static void start() throws InterruptedException {
        //其中一个是处理网络连接,另一个是线程组是处理客户端的链接
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workGroup = new NioEventLoopGroup();
        //启动辅助类
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //设置两个线程组
        serverBootstrap.group(bossGroup,workGroup)
                //精华部分,设置通道的底层实现,通过NioServerSocketChannel,这也是Netty的与NIO搭配的地方(此处作为服务器端通道的实现)
                .channel(NioServerSocketChannel.class)
                //这套机制是在2个小时左右没有接到上层链接时激活
                .option(ChannelOption.SO_KEEPALIVE,true)
                //是否启用心跳保活机制。在双方TCP套接字建立连接后(即都进入ESTABLISHED状态)
                .childOption(ChannelOption.SO_KEEPALIVE,true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    //创建一个通道初始化对象
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        //此处添加规则,自定义的
                        socketChannel.pipeline().addLast(new ServerHandler());
                    }
                });
        ChannelFuture channelFuture = serverBootstrap.bind(8888).sync();
        boolean active = channelFuture.channel().isActive();
        if (active){
            System.out.println("-----服务器启动成功-----");
        }
    }

(2)ServerHandler——规则类,自己定义的

package com.example.netty;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

/**
 * @author by Dong.Ding
 * @Classname ServerHandler
 * @Description TODO 服务器中的业务处理类
 * @Date 2021/9/2 17:40
 */
public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("进入channelActive");
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("进入channelInactive");
        super.channelInactive(ctx);
    }

    /**
     *读取传输来的数据
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("进入channelRead" + byteBuf.toString(CharsetUtil.UTF_8));
        super.channelRead(ctx, msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("进入channelReadComplete");
        super.channelReadComplete(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("进入exceptionCaught");
        super.exceptionCaught(ctx, cause);
    }
}


我在channelRead中打印了一下我发送的数据,我是通过调试助手模拟TCP客户端进行连接的,如下图:
在这里插入图片描述
至此服务端成功,这个channelRead就是通信成功之后用于读取数据的,另外一个打印的进入channelReadComplete是当数据读取完毕时进行的操作


(1)NettyClient——客户端(跟上使用的调试助手是一样的,只不过你这边直接自己写的)

package com.example.netty.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * @author by Dong.Ding
 * @Classname NettyClient
 * @Description TODO
 * @Date 2021/9/3 17:46
 */
public class NettyClient {
    //网络客户端
      public static void main(String[] args) throws Exception{
                     //创建一个线程组(不像服务端需要有连接等待的线程池)
                     EventLoopGroup group = new NioEventLoopGroup();
                     //创建客户端的服务启动助手完成相应配置
                     Bootstrap b = new Bootstrap();
                     b.group(group)
                             .channel(NioSocketChannel.class)
                             //创建一个通道初始化对象
                             .handler(new ChannelInitializer<SocketChannel>() {
                     @Override
                     protected void initChannel(SocketChannel socketChannel) throws Exception {
                                             socketChannel.pipeline().addLast(new NettyClientHandler());//往pipeline中添加自定义的handler
                                         }
                 });
                     System.out.println("...Client is Ready...");
                     //启动客户端去连接服务器端(通过启动助手)
                     ChannelFuture cf = b.connect("127.0.0.1", 9999).sync();
                     //关闭连接(异步非阻塞)
                     cf.channel().closeFuture().sync();

                 }
 }

(2)NettyClientHandler——规则(跟服务端类似,都是要有规则,就是通信处理的一些业务都在这里但是提醒一下,有人说在这里面处理业务会影响效率,最好这边不要涉及到任何的库操作,通过缓存或者redis进行操作,在其他地方再操作

package com.example.netty.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * @author by Dong.Ding
 * @Classname NettyClient
 * @Description TODO
 * @Date 2021/9/3 17:46
 */
public class NettyClient {
    //网络客户端
      public static void main(String[] args) throws Exception{
                     //创建一个线程组(不像服务端需要有连接等待的线程池)
                     EventLoopGroup group = new NioEventLoopGroup();
                     //创建客户端的服务启动助手完成相应配置
                     Bootstrap b = new Bootstrap();
                     b.group(group)
                             .channel(NioSocketChannel.class)
                             //创建一个通道初始化对象
                             .handler(new ChannelInitializer<SocketChannel>() {
                     @Override
                     protected void initChannel(SocketChannel socketChannel) throws Exception {
                     						 //往pipeline中添加自定义的handler
                                             socketChannel.pipeline().addLast(new NettyClientHandler());
                                         }
                 });
                     System.out.println("...Client is Ready...");
                     //启动客户端去连接服务器端(通过启动助手)
                     ChannelFuture cf = b.connect("127.0.0.1", 8888).sync();
                     //关闭连接(异步非阻塞)
                     cf.channel().closeFuture().sync();

                 }
 }

然后我们运行客户端,结果如下:
在这里插入图片描述


也算是完成了最简单的netty通信,很多时候就是业务处理逻辑比较麻烦和处理数据,多了解就会通透很多。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值