0


【Java】Netty创建网络服务端客户端(TCP/UDP)

😏★,°:.☆( ̄▽ ̄)/$:.°★ 😏
这篇文章主要介绍Netty创建网络服务端客户端示例。
学其所用,用其所学。——梁启超
欢迎来到我的博客,一起学习,共同进步。
喜欢的朋友可以关注一下,下次更新不迷路🥞

文章目录

😏1. Netty介绍

Netty官网:

https://netty.io/
Netty

是一个基于Java的异步事件驱动的网络应用程序框架,专门用于快速开发高性能、可扩展和可维护的网络服务器和客户端。它提供了简单而强大的API,使开发人员能够轻松地构建各种网络应用,包括

TCP、UDP、HTTP、WebSocket

等。

以下是一些关键特点和功能:

1.异步和事件驱动:Netty使用非阻塞I/O模型,通过异步事件驱动方式处理网络操作,提供了卓越的性能和可扩展性。

2.高性能:Netty通过有效地利用底层操作系统提供的机制(如选择器、零拷贝等)来实现高效的数据传输和处理,以满足对性能和吞吐量的要求。

3.安全:Netty提供了强大的加密和认证支持,包括SSL/TLS和各种认证机制,保护网络通信的安全性。

4.多协议支持:Netty支持多种主流的网络协议,如TCP、UDP、HTTP、WebSocket等,使开发人员可以方便地构建不同类型的网络应用。

5.灵活的处理程序模型:Netty采用了高度可扩展的处理程序(Handler)模型,使开发人员可以按需配置和组合处理程序来处理网络事件和数据,实现复杂的业务逻辑。

6.内置编解码器:Netty提供了丰富的内置编解码器,使开发人员能够轻松地处理各种协议和数据格式,简化了网络通信中的数据编解码工作。

7.完善的文档和社区支持:Netty拥有完善的官方文档、示例代码和教程,以及活跃的社区支持,使开发人员能够快速上手并解决问题。

😊2. 环境安装与配置

IDEA创建Netty工程,只要在

pom.xml

中引入如下依赖:

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

😆3. TCP应用示例

创建TCP服务端客户端,需要先开启通道

Channel

,然后再有一个事件处理

Handler

,下面就创建这4个类:

在这里插入图片描述

NettyServer.java

packageorg.example;importio.netty.bootstrap.ServerBootstrap;importio.netty.channel.ChannelFuture;importio.netty.channel.ChannelInitializer;importio.netty.channel.ChannelOption;importio.netty.channel.EventLoopGroup;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.SocketChannel;importio.netty.channel.socket.nio.NioServerSocketChannel;importio.netty.handler.logging.LogLevel;importio.netty.handler.logging.LoggingHandler;publicclassNettyServer{privatefinalint port;publicNettyServer(int port){this.port = port;// server port}publicvoidstart()throwsException{EventLoopGroup bossGroup =newNioEventLoopGroup();EventLoopGroup workerGroup =newNioEventLoopGroup();try{ServerBootstrap b =newServerBootstrap();
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG,128).handler(newLoggingHandler(LogLevel.INFO)).childHandler(newChannelInitializer<SocketChannel>(){@OverridepublicvoidinitChannel(SocketChannel ch)throwsException{
                            ch.pipeline().addLast(newNettyServerHandler());// channel to handler}});ChannelFuture f = b.bind(port).sync();System.out.println("Server started on port "+ port);

            f.channel().closeFuture().sync();}finally{
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();}}publicstaticvoidmain(String[] args)throwsException{int port =8080;NettyServer server =newNettyServer(port);
        server.start();}}

NettyServerHandler.java

packageorg.example;importio.netty.buffer.ByteBuf;importio.netty.buffer.Unpooled;importio.netty.channel.*;importio.netty.util.CharsetUtil;publicclassNettyServerHandlerextendsChannelInboundHandlerAdapter{/**
     * 读取数据实际(这里我们可以读取客户端发送的消息)
     * @param ctx 上下文对象
     * @param msg 客户端发送的数据
     * @throws Exception
     */@OverridepublicvoidchannelRead(ChannelHandlerContext ctx,Object msg)throwsException{System.out.println("server ctx ="+ ctx);Channel channel = ctx.channel();// 将 msg 转成一个 ByteBuf// ByteBuf 是 Netty 提供的,不是 NIO 的 ByteBuffer.ByteBuf buf =(ByteBuf) msg;System.out.println("客户端发送的消息是: "+ buf.toString(CharsetUtil.UTF_8));System.out.println("客户端地址: "+ channel.remoteAddress());}/**
     * 读取完毕,回复
     * @param ctx
     * @throws Exception
     */@OverridepublicvoidchannelReadComplete(ChannelHandlerContext ctx)throwsException{// writeAndFlush 是 write + flush 将数据写入到缓存,并刷新
        ctx.writeAndFlush(Unpooled.copiedBuffer("Hello, Client!",CharsetUtil.UTF_8));}/**
     * 处理异常, 一般是需要关闭通道
     * @param ctx
     * @param cause
     * @throws Exception
     */@OverridepublicvoidexceptionCaught(ChannelHandlerContext ctx,Throwable cause)throwsException{
        ctx.close();}}

NettyClient.java

packageorg.example;importio.netty.bootstrap.Bootstrap;importio.netty.channel.ChannelFuture;importio.netty.channel.ChannelInitializer;importio.netty.channel.ChannelOption;importio.netty.channel.EventLoopGroup;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.SocketChannel;importio.netty.channel.socket.nio.NioSocketChannel;publicclassNettyClient{privatefinalString host;privatefinalint port;publicNettyClient(String host,int port){this.host = host;// ipthis.port = port;// port}publicvoidstart()throwsException{EventLoopGroup group =newNioEventLoopGroup();try{Bootstrap b =newBootstrap();
            b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY,true).handler(newChannelInitializer<SocketChannel>(){@OverridepublicvoidinitChannel(SocketChannel ch)throwsException{
                            ch.pipeline().addLast(newNettyClientHandler());}});ChannelFuture f = b.connect(host, port).sync();System.out.println("Connected to "+ host +":"+ port);

            f.channel().closeFuture().sync();}finally{
            group.shutdownGracefully();}}publicstaticvoidmain(String[] args)throwsException{String host ="localhost";int port =8080;NettyClient client =newNettyClient(host, port);
        client.start();}}

NettyClientHandler.java

packageorg.example;importio.netty.buffer.ByteBuf;importio.netty.buffer.Unpooled;importio.netty.channel.ChannelHandlerContext;importio.netty.channel.ChannelInboundHandlerAdapter;importio.netty.util.CharsetUtil;publicclassNettyClientHandlerextendsChannelInboundHandlerAdapter{/**
     * 通道创建就绪后触发
     * @param ctx
     * @throws Exception
     */@OverridepublicvoidchannelActive(ChannelHandlerContext ctx)throwsException{System.out.println("client ctx ="+ ctx);
        ctx.writeAndFlush(Unpooled.copiedBuffer("Hello, Server!",CharsetUtil.UTF_8));}/**
     * 当通道有读取事件时,会触发
     * @param ctx
     * @param msg
     * @throws Exception
     */@OverridepublicvoidchannelRead(ChannelHandlerContext ctx,Object msg)throwsException{ByteBuf buf =(ByteBuf) msg;System.out.println("服务器回复的消息:"+ buf.toString(CharsetUtil.UTF_8));System.out.println("服务器的地址: "+ ctx.channel().remoteAddress());}/**
     * 处理异常, 一般是需要关闭通道
     * @param ctx
     * @param cause
     * @throws Exception
     */@OverridepublicvoidexceptionCaught(ChannelHandlerContext ctx,Throwable cause)throwsException{
        cause.printStackTrace();
        ctx.close();}}

分别运行服务端和客户端类,结果如下:

在这里插入图片描述

😆4. UDP应用示例

跟上面TCP类似,UDP也是要创建Channel和Handler,下面创建这4个类:

在这里插入图片描述

UDPServer.java

packageorg.example;importio.netty.bootstrap.Bootstrap;importio.netty.channel.ChannelFuture;importio.netty.channel.ChannelInitializer;importio.netty.channel.EventLoopGroup;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.DatagramChannel;importio.netty.channel.socket.nio.NioDatagramChannel;publicclassUDPServer{privatefinalint port;publicUDPServer(int port){this.port = port;}publicvoidstart()throwsException{EventLoopGroup group =newNioEventLoopGroup();try{Bootstrap b =newBootstrap();
            b.group(group).channel(NioDatagramChannel.class).handler(newChannelInitializer<DatagramChannel>(){@OverrideprotectedvoidinitChannel(DatagramChannel ch)throwsException{
                            ch.pipeline().addLast(newUDPServerHandler());}});ChannelFuture f = b.bind(port).sync();System.out.println("Server started on port "+ port);
            f.channel().closeFuture().sync();}finally{
            group.shutdownGracefully();}}publicstaticvoidmain(String[] args)throwsException{int port =8888;UDPServer server =newUDPServer(port);
        server.start();}}

UDPServerHandler.java

packageorg.example;importio.netty.buffer.Unpooled;importio.netty.channel.ChannelHandlerContext;importio.netty.channel.SimpleChannelInboundHandler;importio.netty.channel.socket.DatagramPacket;importio.netty.util.CharsetUtil;publicclassUDPServerHandlerextendsSimpleChannelInboundHandler<DatagramPacket>{@OverrideprotectedvoidchannelRead0(ChannelHandlerContext ctx,DatagramPacket msg)throwsException{// 处理接收到的数据String receivedMessage = msg.content().toString(CharsetUtil.UTF_8);System.out.println("Received message: "+ receivedMessage);// 响应客户端String responseMessage ="Hello, client!";DatagramPacket responsePacket =newDatagramPacket(Unpooled.copiedBuffer(responseMessage,CharsetUtil.UTF_8),
                msg.sender());
        ctx.writeAndFlush(responsePacket);}}

UDPClient.java

packageorg.example;importio.netty.bootstrap.Bootstrap;importio.netty.buffer.Unpooled;importio.netty.channel.ChannelFuture;importio.netty.channel.ChannelInitializer;importio.netty.channel.EventLoopGroup;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.DatagramChannel;importio.netty.channel.socket.DatagramPacket;importio.netty.channel.socket.nio.NioDatagramChannel;importio.netty.util.CharsetUtil;importjava.net.InetSocketAddress;publicclassUDPClient{privatefinalString host;privatefinalint port;publicUDPClient(String host,int port){this.host = host;this.port = port;}publicvoidstart()throwsException{EventLoopGroup group =newNioEventLoopGroup();try{Bootstrap b =newBootstrap();
            b.group(group).channel(NioDatagramChannel.class).handler(newChannelInitializer<DatagramChannel>(){@OverrideprotectedvoidinitChannel(DatagramChannel ch)throwsException{
                            ch.pipeline().addLast(newUDPClientHandler());}});ChannelFuture f = b.bind(0).sync();System.out.println("Client started");// 发送消息给服务端String message ="Hello, server!";DatagramPacket packet =newDatagramPacket(Unpooled.copiedBuffer(message,CharsetUtil.UTF_8),newInetSocketAddress(host, port));
            f.channel().writeAndFlush(packet).sync();

            f.channel().closeFuture().sync();}finally{
            group.shutdownGracefully();}}publicstaticvoidmain(String[] args)throwsException{String host ="localhost";int port =8888;UDPClient client =newUDPClient(host, port);
        client.start();}}

UDPClientHandler.java

packageorg.example;importio.netty.channel.ChannelHandlerContext;importio.netty.channel.SimpleChannelInboundHandler;importio.netty.channel.socket.DatagramPacket;importio.netty.util.CharsetUtil;publicclassUDPClientHandlerextendsSimpleChannelInboundHandler<DatagramPacket>{@OverrideprotectedvoidchannelRead0(ChannelHandlerContext ctx,DatagramPacket msg)throwsException{// 处理接收到的数据String receivedMessage = msg.content().toString(CharsetUtil.UTF_8);System.out.println("Received response from server: "+ receivedMessage);}}

运行结果如下:

在这里插入图片描述

请添加图片描述

以上。


本文转载自: https://blog.csdn.net/qq_40344790/article/details/134305614
版权归原作者 DevFrank 所有, 如有侵权,请联系我们删除。

“【Java】Netty创建网络服务端客户端(TCP/UDP)”的评论:

还没有评论