Netty入门,开发一个简单的服务器端和客户端,不玩虚的直接上代码!(已完善客户端代码!粘贴启动即可!)

Netty 是什么?

先看看官网这段“英格力士”

Netty is an asynchronous event-driven network application framework
for rapid development of maintainable high performance protocol servers & clients.

Netty 是一个异步的、基于事件驱动的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端

现在,用netty开发一个简单的服务器端和客户端,实现客户端发送消息给服务端,服务端收到之后反馈给客户端。

首先构建一个maven项目,名字自己随便取就行,构建好了之后再pom.xml引入依赖:

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.39.Final</version>
</dependency>

创建NettyServer启动类

import com.niit.sky.serverHandler.ServerChildHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Sky.yu
 * @ClassName NettyServer.java
 * @Description 服务器启动类
 * @createTime 2022-08-13 12:44
 **/
@Slf4j
public class NettyServer {
    private final Integer PORT;

    public NettyServer(Integer port) {
        this.PORT = port;
    }

    public void startNettyServer() throws InterruptedException {
        NioEventLoopGroup boss = new NioEventLoopGroup();
        NioEventLoopGroup worker = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap
                    //EventLoop = selector 检测 + thread 线程
                    .group(boss, worker)
                    //选择服务器的实现
                    .channel(NioServerSocketChannel.class)
                    //handler
                    .childHandler(new ServerChildHandler());

            ChannelFuture channelFuture = serverBootstrap
                    .bind(PORT)
                    .sync();
            log.info("Netty服务器启动成功!");
            channelFuture
                    .channel()
                    .closeFuture()
                    .sync();
        } catch (Exception e) {
            log.error("Netty服务器运行出错,错误信息————>{}",e.getMessage());
        } finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new NettyServer(8899).startNettyServer();
    }

}


创建ServerChildHandler类,添加handler:

import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LoggingHandler;

/**
 * @author Sky.yu
 * @ClassName serverChildHandler.java
 * @Description 负责连接worker、处理读写
 * @createTime 2022-08-13 12:51
 **/

public class ServerChildHandler extends ChannelInitializer<NioSocketChannel> {
    @Override
    protected void initChannel(NioSocketChannel ch) throws Exception {
        ch.pipeline().addLast(new LoggingHandler());
        //编码 string转成ByteBuf
        ch.pipeline().addLast(new StringEncoder());
        //解码
        ch.pipeline().addLast(new StringDecoder());
        //自定义handler
        ch.pipeline().addLast(new ServerHandler());

    }
}

创建自定义handler类ServerHandler,继承了ChannelInboundHandlerAdapter,具体方法说明可看方法说明

@Slf4j
public class ServerHandler extends ChannelInboundHandlerAdapter {

    /**
     * 读事件
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 打印上一步转换好的字符串
        System.out.println("收到来自"+ctx.channel()+"的消息:"+msg.toString());
        ctx.channel().writeAndFlush("收到你的信息了!");
    }

}

下面是客户端:
nettyClient:


import com.sky.mynettydemo.handler.ClientHandler.ClientChildHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;

/**
* @author Sky.yu
* @ClassName NettyClient.java
* @Description 客户端
* @createTime 2022-08-13 13:06
**/
@Slf4j
public class NettyClient {

   private final String HOST;
   private final Integer PORT;

   public NettyClient(String host,Integer port) {
       this.HOST = host;
       this.PORT = port;
   }

   public void startNettyClient() {
       NioEventLoopGroup boss = new NioEventLoopGroup();
       try {
           //启动类
           Bootstrap bootstrap = new Bootstrap();
           Bootstrap handler = bootstrap
                   //添加eventLoop
                   .group(boss)
                   //选择客户端channel实现
                   .channel(NioSocketChannel.class)
                   //添加处理器
                   .handler(new ClientChildHandler());

           ChannelFuture channelFuture = handler
                   .connect(HOST, PORT)
                   //阻塞方法,直到连接建立才继续执行
                   .sync();
           log.info("Netty客户端连接服务器成功!");
           //代表连接对象
           Channel channel = channelFuture.channel();

           channel.closeFuture().sync();
       } catch (Exception e) {
           log.debug("客户端连接错误!信息——>{}",e);
       } finally {
           boss.shutdownGracefully();
           log.debug("客户端关闭连接!");
       }
   }


   public static void main(String[] args) throws InterruptedException {
       new NettyClient("127.0.0.1",8899).startNettyClient();
   }

}

下面是handler,
ClientChildHandler:


import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

/**
 * @author Sky.yu
 * @ClassName ClientChildHandler.java
 * @Description
 * @createTime 2022-08-13 13:31
 **/

public class ClientChildHandler extends ChannelInitializer<NioSocketChannel> {
    @Override
    protected void initChannel(NioSocketChannel ch) throws Exception {
        //编码  string转成ByteBuf
        ch.pipeline().addLast(new StringEncoder());
        //解码
        ch.pipeline().addLast(new StringDecoder());
        //自定义handler
        ch.pipeline().addLast(new ClientHandler());
    }
}

自定义ClientHandler

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Sky.yu
 * @ClassName ClientHandler.java
 * @Description 客户端处理器
 * @createTime 2022-08-13 13:31
 **/
@Slf4j
public class ClientHandler extends ChannelInboundHandlerAdapter {

    /**
     * active 连接建立成功后,触发该方法!
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ChannelFuture channelFuture = ctx.channel().writeAndFlush("你好,服务端!我是客户端!");
        if (channelFuture.isSuccess()) log.info("客户端发送消息成功!");
    }

    /**
     * 读事件
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("收到来自服务端的消息:"+msg);
    }
}

然后启动服务端,再启动客户端即可,效果图如下:
服务端控制台
客户端控制台

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天龙真人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值