zoukankan      html  css  js  c++  java
  • 基于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

  • 相关阅读:
    windows系统切换jdk,修改java_home无效情况
    Cannot instantiate interface org.springframework.context.ApplicationListener
    MySQL分组查询获取每个学生前n条分数记录(分组查询前n条记录)
    ASP.NET Web API 使用Swagger生成在线帮助测试文档,支持多个GET
    EF TO MYSQL 无法查询中文的解决方法
    HttpWebRequest post请求获取webservice void数据信息
    This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms. 此实现不是 Windows 平台 FIPS 验证的加密算法的一部分 解决方案
    MySQL 5.7.13解压版安装记录 mysql无法启动教程
    C# udpclient 发送数据断网后自动连接的方法
    汽车XX网站秒杀抢购代码
  • 原文地址:https://www.cnblogs.com/billmiao/p/9872166.html
Copyright © 2011-2022 走看看