简述

编写一个简单的 netty 实现的客户端和服务端程序,以及知悉其流程

服务端

  1. package cn.inetty.netty;
  2. import io.netty.bootstrap.ServerBootstrap;
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.ChannelInboundHandlerAdapter;
  5. import io.netty.channel.ChannelInitializer;
  6. import io.netty.channel.nio.NioEventLoopGroup;
  7. import io.netty.channel.socket.nio.NioServerSocketChannel;
  8. import io.netty.channel.socket.nio.NioSocketChannel;
  9. import io.netty.handler.codec.string.StringDecoder;
  10. // 使用 netty 实现服务器和客户端
  11. public class HelloServer {
  12. public static void main(String[] args) {
  13. // 1. ServerBootstrap 是一个服务器启动器 负责组装 netty 组件并启动服务器
  14. new ServerBootstrap()
  15. // 2. 包含 BossEventLoop 和 WorkerEventLoop(selector, thread)
  16. .group(new NioEventLoopGroup())
  17. // 3. 选择 NioServerSocketChannel 实现作为服务器通道
  18. .channel(NioServerSocketChannel.class)
  19. // 4. netty 提供了 很多 handler 这些 handler 提供不同的功能 通过 childHandler 添加 handler 的方式可以决定 worker 处理那些事情
  20. .childHandler(
  21. // 5. ChannelInitializer 用于初始化通道并负责添加 handler 通道可以和客户端进行数据读写
  22. new ChannelInitializer<NioSocketChannel>() {
  23. @Override
  24. protected void initChannel(NioSocketChannel nch) throws Exception {
  25. // 6. 添加具体的 handler
  26. nch.pipeline().addLast(new StringDecoder()); // StringDecoder 将 ByteBuf 转换成 String
  27. // 7. 自定义了一个 handler
  28. nch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
  29. // 触发读事件
  30. @Override
  31. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  32. // 打印 StringDecoder 转换的字符串
  33. System.out.println(msg);
  34. }
  35. });
  36. }
  37. })
  38. // 8. 绑定 NioServerSocketChannel 的监听端口
  39. .bind(8888);
  40. }
  41. }

客户端

  1. package cn.inetty.netty;
  2. import io.netty.bootstrap.Bootstrap;
  3. import io.netty.channel.ChannelInitializer;
  4. import io.netty.channel.nio.NioEventLoopGroup;
  5. import io.netty.channel.socket.nio.NioSocketChannel;
  6. import io.netty.handler.codec.string.StringEncoder;
  7. import java.net.InetSocketAddress;
  8. public class HelloClient {
  9. public static void main(String[] args) throws InterruptedException {
  10. // 1. 启动类
  11. new Bootstrap()
  12. // 2. 添加 EventLoop
  13. .group(new NioEventLoopGroup())
  14. // 3. 选择 channel 实现
  15. .channel(NioSocketChannel.class)
  16. // 4. 添加 handler
  17. .handler(new ChannelInitializer<NioSocketChannel>() {
  18. @Override // initChannel 在建立连接时被调用
  19. protected void initChannel(NioSocketChannel nsc) throws Exception {
  20. nsc.pipeline().addLast(new StringEncoder());
  21. }
  22. })
  23. // 5. 连接到服务器
  24. .connect(new InetSocketAddress("localhost", 8888))
  25. .sync() // 阻塞方法 等待连接建立
  26. .channel() // 连接对象
  27. // 6 向服务器发送数据
  28. .writeAndFlush("hello, netty");
  29. }
  30. }

执行流程

Snip20210430_1.png