博客
关于我
Netty的Socket编程详解-搭建服务端与客户端并进行数据传输
阅读量:789 次
发布时间:2023-02-15

本文共 6163 字,大约阅读时间需要 20 分钟。

Netty在IDEA中搭建HelloWorld服务端并对Netty执行流程与重要组件进行介绍

Netty是一款强大的异步I/O框架,广泛应用于网络应用开发。为了帮助开发者快速入门,以下将详细介绍如何使用Netty搭建HelloWorld服务端与客户端,并实现数据传输。

场景

在本节中,我们将通过Netty实现一个简单的Socket通信应用。服务端和客户端将通过Netty进行数据的交互,展示Netty的基本功能和优势。

实现

Socket服务端搭建

  • 创建服务端类

    src目录下新建包com.badao.nettySocket,并在该包下创建服务端类SocketServer。该类将继承自ServerBootstrap并包含main方法。

    package com.badao.nettySocket;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;public class SocketServer {    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 SocketServerInitializer());            ChannelFuture channelFuture = serverBootstrap.bind(70).sync();            channelFuture.channel().closeFuture().sync();        } finally {            bossGroup.shutdownGracefully();            workerGroup.shutdownGracefully();        }    }}
  • 创建服务端初始化器

    服务端初始化器SocketServerInitializer继承自ChannelInitializer,并添加必要的处理器。

    package com.badao.nettySocket;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.LengthFieldBasedFrameDecoder;import io.netty.handler.codec.LengthFieldPrepender;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.util.CharsetUtil;public class SocketServerInitializer extends ChannelInitializer
    { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); pipeline.addLast(new LengthFieldPrepender(4)); pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); pipeline.addLast(new SocketServerHandler()); }}
  • 创建服务端处理器

    服务端处理器SocketServerHandler继承自SimpleChannelInboundHandler,用于处理客户端发送的数据。

    package com.badao.nettySocket;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;public class SocketServerHandler extends SimpleChannelInboundHandler
    { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println("服务端收到来自" + ctx.channel().remoteAddress() + "的" + msg); ctx.channel().writeAndFlush("服务端发送的数据:(公众号:霸道的程序猿)"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); }}
  • Socket客户端搭建

  • 创建客户端类

    com.badao.nettySocket包下创建客户端类SocketClient,该类继承自Bootstrap并包含main方法。

    package com.badao.nettySocket;import io.netty.bootstrap.Bootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioSocketChannel;public class SocketClient {    public static void main(String[] args) throws Exception {        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();        try {            Bootstrap bootstrap = new Bootstrap();            bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)                        .handler(new SocketClientInitializer());            ChannelFuture channelFuture = bootstrap.connect("localhost", 70).sync();            channelFuture.channel().closeFuture().sync();        } finally {            eventLoopGroup.shutdownGracefully();        }    }}
  • 创建客户端初始化器

    客户端初始化器SocketClientInitializer继承自ChannelInitializer,并添加必要的处理器。

    package com.badao.nettySocket;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.LengthFieldBasedFrameDecoder;import io.netty.handler.codec.LengthFieldPrepender;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.util.CharsetUtil;public class SocketClientInitializer extends ChannelInitializer
    { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); pipeline.addLast(new LengthFieldPrepender(4)); pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); pipeline.addLast(new SocketClientHandler()); }}
  • 创建客户端处理器

    客户端处理器SocketClientHandler继承自SimpleChannelInboundHandler,用于处理服务端发送的数据。

    package com.badao.nettySocket;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;public class SocketClientHandler extends SimpleChannelInboundHandler
    { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println("客户端收到来自" + ctx.channel().remoteAddress() + "的" + msg); ctx.channel().writeAndFlush("客户端向服务端发送的数据:(公众号:霸道的程序猿)"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); }}
  • 数据传输实现

    在客户端的channelActive方法中添加数据发送逻辑,确保客户端在连接建立后立即发送数据。

    @Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {    ctx.writeAndFlush("客户端发来消息");}

    通过以上步骤,服务端和客户端的通信流程如下:

  • 服务端启动:服务端监听指定端口,等待客户端连接。
  • 客户端启动:客户端连接到服务端指定的地址和端口。
  • 连接建立:客户端在channelActive方法中发送数据,触发服务端处理。
  • 数据处理:服务端处理客户端发送的数据,并向客户端发送响应。
  • 数据循环:客户端接收响应并重复发送数据,服务端持续处理。
  • 运行与调试

  • 编译与运行:将服务端和客户端的相关类编译,并分别运行它们的main方法。
  • 验证通信:检查输出日志,确保服务端接收到客户端的数据,并客户端接收到服务端的响应。
  • 通过以上步骤,您成功搭建并实现了一个使用Netty的Socket通信应用,展示了服务端与客户端之间的数据传输流程。Netty的强大功能使得开发高性能网络应用变得更加容易,同时代码的可读性和可维护性也得到了提升。

    转载地址:http://mvcfk.baihongyu.com/

    你可能感兴趣的文章
    Netty框架的服务端开发中创建EventLoopGroup对象时线程数量源码解析
    查看>>
    Netty源码—1.服务端启动流程一
    查看>>
    Netty源码—1.服务端启动流程二
    查看>>
    Netty源码—2.Reactor线程模型一
    查看>>
    Netty源码—2.Reactor线程模型二
    查看>>
    Netty源码—3.Reactor线程模型三
    查看>>
    Netty源码—3.Reactor线程模型四
    查看>>
    Netty源码—4.客户端接入流程一
    查看>>
    Netty源码—4.客户端接入流程二
    查看>>
    Netty源码—5.Pipeline和Handler一
    查看>>
    Netty源码—5.Pipeline和Handler二
    查看>>
    Netty源码—6.ByteBuf原理一
    查看>>
    Netty源码—6.ByteBuf原理二
    查看>>
    Netty源码—7.ByteBuf原理三
    查看>>
    Netty源码—7.ByteBuf原理四
    查看>>
    Netty源码—8.编解码原理一
    查看>>
    Netty源码—8.编解码原理二
    查看>>
    Netty源码解读
    查看>>
    netty的HelloWorld演示
    查看>>
    Netty的Socket编程详解-搭建服务端与客户端并进行数据传输
    查看>>