• 基于socket的netty demo


    前面一文说了 基于http的netty demo

    和http不一样,http可以用浏览器来充当客户端调用,所以基于socket的netty,必须要编写客户端和服务器的代码

    实现功能:
    客户端给服务器发消息,服务器给客户端回消息
    一直循环

    服务器代码

     1 package com.bill.socketdemo;
     2 
     3 
     4 import io.netty.bootstrap.ServerBootstrap;
     5 import io.netty.channel.ChannelFuture;
     6 import io.netty.channel.EventLoopGroup;
     7 import io.netty.channel.nio.NioEventLoopGroup;
     8 import io.netty.channel.socket.nio.NioServerSocketChannel;
     9 
    10 public class SocketServer {
    11 
    12     public static void main(String[] args) throws Exception {
    13 
    14         // 这2个group都是死循环,阻塞式
    15         EventLoopGroup bossGroup = new NioEventLoopGroup();
    16         EventLoopGroup workerGroup = new NioEventLoopGroup();
    17 
    18         try {
    19             ServerBootstrap serverBootstrap = new ServerBootstrap();
    20             serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).
    21                     childHandler(new SocketServerInitializer());
    22 
    23             ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
    24             channelFuture.channel().closeFuture().sync();
    25         } finally {
    26             bossGroup.shutdownGracefully();
    27             workerGroup.shutdownGracefully();
    28         }
    29     }
    30 
    31 }
    32 
    33 package com.bill.socketdemo;
    34 
    35 import io.netty.channel.ChannelHandlerContext;
    36 import io.netty.channel.SimpleChannelInboundHandler;
    37 
    38 import java.util.UUID;
    39 
    40 public class SocketServerHandler extends SimpleChannelInboundHandler<String> {
    41 
    42     /**
    43      * 读取客户端请求,并且返回给客户端数据的方法
    44      */
    45     @Override
    46     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
    47         System.out.println(ctx.channel().remoteAddress() + ", " + msg);
    48         ctx.channel().writeAndFlush("from server:" + UUID.randomUUID());
    49     }
    50 
    51     /**
    52      * 处理异常的方法,一旦出现异常,就会调用此方法
    53      */
    54     @Override
    55     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    56         cause.printStackTrace();
    57         ctx.close();
    58     }
    59 }
    60 
    61 package com.bill.socketdemo;
    62 
    63 import io.netty.channel.ChannelInitializer;
    64 import io.netty.channel.ChannelPipeline;
    65 import io.netty.channel.socket.SocketChannel;
    66 import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
    67 import io.netty.handler.codec.LengthFieldPrepender;
    68 import io.netty.handler.codec.string.StringDecoder;
    69 import io.netty.handler.codec.string.StringEncoder;
    70 import io.netty.util.CharsetUtil;
    71 
    72 public class SocketServerInitializer extends ChannelInitializer<SocketChannel> {
    73 
    74     @Override
    75     protected void initChannel(SocketChannel socketChannel) throws Exception {
    76 
    77         ChannelPipeline pipeline = socketChannel.pipeline();
    78 
    79         pipeline.addLast("LengthFieldBasedFrameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
    80         pipeline.addLast("LengthFieldPrepender",new LengthFieldPrepender(4));
    81         pipeline.addLast("StringDecoder",new StringDecoder(CharsetUtil.UTF_8));
    82         pipeline.addLast("StringEncoder",new StringEncoder(CharsetUtil.UTF_8));
    83         pipeline.addLast("SocketServerHandler", new SocketServerHandler());
    84     }
    85 }

     

    客户端代码

     1 package com.bill.socketdemo;
     2 
     3 
     4 import io.netty.bootstrap.Bootstrap;
     5 import io.netty.channel.ChannelFuture;
     6 import io.netty.channel.EventLoopGroup;
     7 import io.netty.channel.nio.NioEventLoopGroup;
     8 import io.netty.channel.socket.nio.NioSocketChannel;
     9 
    10 public class SocketClient {
    11 
    12     public static void main(String[] args) throws Exception {
    13 
    14         // 这2个group都是死循环,阻塞式
    15         EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
    16 
    17         try {
    18             Bootstrap bootstrap = new Bootstrap();
    19             bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).
    20                     handler(new SocketClientInitializer());
    21 
    22             ChannelFuture channelFuture = bootstrap.connect("localhost", 8899).sync();
    23             channelFuture.channel().closeFuture().sync();
    24         } finally {
    25             eventLoopGroup.shutdownGracefully();
    26         }
    27     }
    28 
    29 }
    30 
    31 package com.bill.socketdemo;
    32 
    33 import io.netty.channel.ChannelHandlerContext;
    34 import io.netty.channel.SimpleChannelInboundHandler;
    35 
    36 import java.util.UUID;
    37 
    38 public class SocketClientHandler extends SimpleChannelInboundHandler<String> {
    39 
    40     /**
    41      * 发送内容给服务器端
    42      */
    43     @Override
    44     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
    45         System.out.println(ctx.channel().remoteAddress());
    46         System.out.println("client output:" + msg);
    47         ctx.writeAndFlush("from client:" + UUID.randomUUID());
    48     }
    49 
    50     /**
    51      * 该方法向服务器发数据,打破服务器-客户端一直等待对方发数据的僵局
    52      */
    53     @Override
    54     public void channelActive(ChannelHandlerContext ctx) throws Exception {
    55         ctx.writeAndFlush("from client: hello world");
    56     }
    57 
    58     /**
    59      * 处理异常的方法,一旦出现异常,就会调用此方法
    60      */
    61     @Override
    62     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    63         cause.printStackTrace();
    64         ctx.close();
    65     }
    66 }
    67 
    68 package com.bill.socketdemo;
    69 
    70 import io.netty.channel.ChannelInitializer;
    71 import io.netty.channel.ChannelPipeline;
    72 import io.netty.channel.socket.SocketChannel;
    73 import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
    74 import io.netty.handler.codec.LengthFieldPrepender;
    75 import io.netty.handler.codec.string.StringDecoder;
    76 import io.netty.handler.codec.string.StringEncoder;
    77 import io.netty.util.CharsetUtil;
    78 
    79 public class SocketClientInitializer extends ChannelInitializer<SocketChannel> {
    80 
    81     @Override
    82     protected void initChannel(SocketChannel socketChannel) throws Exception {
    83 
    84         ChannelPipeline pipeline = socketChannel.pipeline();
    85 
    86         pipeline.addLast("LengthFieldBasedFrameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
    87         pipeline.addLast("LengthFieldPrepender",new LengthFieldPrepender(4));
    88         pipeline.addLast("StringDecoder",new StringDecoder(CharsetUtil.UTF_8));
    89         pipeline.addLast("StringEncoder",new StringEncoder(CharsetUtil.UTF_8));
    90         pipeline.addLast("SocketServerHandler", new SocketClientHandler());
    91     }
    92 }

    执行结果

    先运行服务器:

    再运行客户端:

    运行完客户端后服务器的情况

    完整代码下载:

    https://download.csdn.net/download/mweibiao/10551574

  • 相关阅读:
    有向无环图描述表达式 (a+b)*((a+b)/a)至少需要的顶点数目
    图的深度优先是 树的先序遍历的推广。 广度优先
    leader failed to send out heartbeat on time; took too long, leader is overloaded likely from slow disk
    优化 并发
    最终一致和强一致性缓存实践
    Go语言逆向初探 原创 半个大西瓜 看雪学院 2021-06-23
    中通快递的云原生改造之路 施尧 InfoQ 2021-06-23
    Stable Minimum Storage Merging by Symmetric Comparisons Pok-Son Kim1? and Arne Kutzner2
    A Method for the Construction of Minimum-Redundancy Codes
    滴滴基于Binlog的采集架构与实践 原创 滴滴技术团队 滴滴技术 2021-06-22
  • 原文地址:https://www.cnblogs.com/billmiao/p/9872166.html
Copyright © 2020-2023  润新知