区块链技术博客
www.b2bchain.cn

Netty入门-实现一个时间服务器求职学习资料

D0b2wT.gif

本文介绍了Netty入门-实现一个时间服务器求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

功能描述 :
客户端通过指令Code获取获取对应的年月日信息

该项目共三个模块
1.common
2.client
3.server

1.公共模块

自定义协议类:

public class RemotingCommand implements Serializable {     public static final int YEAR_REQUEST = 1;     public static final int MONTH_REQUEST = 2;     public static final int DAY_REQUEST = 3;     private int code;     private String body;      public int getCode() {         return code;     }      public void setCode(int code) {         this.code = code;     }      public String getBody() {         return body;     }      public void setBody(String body) {         this.body = body;     } }

2.服务端代码

2.1 服务器启动类

public class ServerMain {     public static void main(String[] args) {         TimeServer timeServer = new TimeServer();         timeServer.bind();     } }

2.2 时间服务器

package com.netty.server;  import java.util.concurrent.ConcurrentHashMap; import com.netty.common.Config; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel;  /**  * Created by yzy on 2020-11-04  */ public class TimeServer {     /** 可以用于保存所有的客户端连接channel , 参考rocketMQ的做法 **/     private final ConcurrentHashMap<String, Channel> clientChannelTable = new ConcurrentHashMap<String, Channel>(5);      public  void bind() {         EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup();         EventLoopGroup workerEventLoopGroup = new NioEventLoopGroup();         try {             ServerBootstrap serverBootstrap = new ServerBootstrap();             serverBootstrap.group(bossEventLoopGroup, workerEventLoopGroup)                     .channel(NioServerSocketChannel.class)                     .option(ChannelOption.SO_BACKLOG, 1024)                     .childHandler(new ServerChannelHandler());              System.out.println("server start");             ChannelFuture channelFuture = serverBootstrap.bind(Config.PORT).sync();             channelFuture.channel().closeFuture().sync();         } catch (InterruptedException e) {             e.printStackTrace();         }finally {             bossEventLoopGroup.shutdownGracefully();             workerEventLoopGroup.shutdownGracefully();         }     } }

2.3 ServerChannelHandler

因为需要序列化RemotingCommand对象, 所以需要引入ObjectEncoder来解决半包粘包的问题

package com.netty.server; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.serialization.ClassResolvers; import io.netty.handler.codec.serialization.ObjectDecoder; import io.netty.handler.codec.serialization.ObjectEncoder;  /**  * Created by yzy on 2020-11-04  */ public class ServerChannelHandler extends ChannelInitializer<SocketChannel> {     @Override     protected void initChannel(SocketChannel socketChannel) throws Exception {         // 添加对象解码器 负责对序列化POJO对象进行解码 设置对象序列化最大长度为1M 防止内存溢出         // 设置线程安全的WeakReferenceMap对类加载器进行缓存 支持多线程并发访问 防止内存溢出         socketChannel.pipeline().addLast(                 new ObjectDecoder(1024 * 1024, ClassResolvers                         .weakCachingConcurrentResolver(this.getClass()                                 .getClassLoader())));         // 添加对象编码器 在服务器对外发送消息的时候自动将实现序列化的POJO对象编码         socketChannel.pipeline().addLast(new ObjectEncoder());          socketChannel.pipeline().addLast(new TimeServerHandler());     } }

2.4 TimeServerHandler

package com.netty.server;  import java.util.Calendar; import com.netty.common.RemotingCommand; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler;  /**  * Created by yzy on 2020-11-04  */ public class TimeServerHandler extends SimpleChannelInboundHandler<RemotingCommand> {      @Override     public void channelRead0(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception {        System.out.println("server read " + msg.getCode());       if(msg.getCode() == RemotingCommand.YEAR_REQUEST){           int year = Calendar.getInstance().get(Calendar.YEAR);           RemotingCommand resp = new RemotingCommand();           resp.setBody(year + "年");           ctx.write(resp);       }         if(msg.getCode() == RemotingCommand.DAY_REQUEST){             int day = Calendar.getInstance().get(Calendar.DATE);             RemotingCommand resp = new RemotingCommand();             resp.setBody(day + "日");             ctx.write(resp);         }         if(msg.getCode() == RemotingCommand.MONTH_REQUEST){             int month = Calendar.getInstance().get(Calendar.MONTH) + 1;             RemotingCommand resp = new RemotingCommand();             resp.setBody(month + "月");             ctx.write(resp);         }     }      @Override     public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {         super.channelReadComplete(ctx);         ctx.flush();     }      @Override     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {         super.exceptionCaught(ctx, cause);         ctx.close();     } }

3.客户端代码

3.1 客户端主类

“`
public class ClientMain {
public static void main(String[] args) throws InterruptedException {
TimeClient timeClient = new TimeClient();
//连接服务
timeClient.connet(Config.PORT, Config.IP);
//用户交互
Scanner ip = new Scanner(System.in);;
boolean isExit = false;
while(!isExit){
System.out.println(“请输入 1:获取年 2:获取月 3:获取日 4:退出 “);
int ops = ip.nextInt();
if(ops == 1){
RemotingCommand request = new RemotingCommand();

功能描述 :
客户端通过指令Code获取获取对应的年月日信息

该项目共三个模块
1.common
2.client
3.server

1.公共模块

自定义协议类:

public class RemotingCommand implements Serializable {     public static final int YEAR_REQUEST = 1;     public static final int MONTH_REQUEST = 2;     public static final int DAY_REQUEST = 3;     private int code;     private String body;      public int getCode() {         return code;     }      public void setCode(int code) {         this.code = code;     }      public String getBody() {         return body;     }      public void setBody(String body) {         this.body = body;     } }

2.服务端代码

2.1 服务器启动类

public class ServerMain {     public static void main(String[] args) {         TimeServer timeServer = new TimeServer();         timeServer.bind();     } }

2.2 时间服务器

package com.netty.server;  import java.util.concurrent.ConcurrentHashMap; import com.netty.common.Config; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel;  /**  * Created by yzy on 2020-11-04  */ public class TimeServer {     /** 可以用于保存所有的客户端连接channel , 参考rocketMQ的做法 **/     private final ConcurrentHashMap<String, Channel> clientChannelTable = new ConcurrentHashMap<String, Channel>(5);      public  void bind() {         EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup();         EventLoopGroup workerEventLoopGroup = new NioEventLoopGroup();         try {             ServerBootstrap serverBootstrap = new ServerBootstrap();             serverBootstrap.group(bossEventLoopGroup, workerEventLoopGroup)                     .channel(NioServerSocketChannel.class)                     .option(ChannelOption.SO_BACKLOG, 1024)                     .childHandler(new ServerChannelHandler());              System.out.println("server start");             ChannelFuture channelFuture = serverBootstrap.bind(Config.PORT).sync();             channelFuture.channel().closeFuture().sync();         } catch (InterruptedException e) {             e.printStackTrace();         }finally {             bossEventLoopGroup.shutdownGracefully();             workerEventLoopGroup.shutdownGracefully();         }     } }

2.3 ServerChannelHandler

因为需要序列化RemotingCommand对象, 所以需要引入ObjectEncoder来解决半包粘包的问题

package com.netty.server; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.serialization.ClassResolvers; import io.netty.handler.codec.serialization.ObjectDecoder; import io.netty.handler.codec.serialization.ObjectEncoder;  /**  * Created by yzy on 2020-11-04  */ public class ServerChannelHandler extends ChannelInitializer<SocketChannel> {     @Override     protected void initChannel(SocketChannel socketChannel) throws Exception {         // 添加对象解码器 负责对序列化POJO对象进行解码 设置对象序列化最大长度为1M 防止内存溢出         // 设置线程安全的WeakReferenceMap对类加载器进行缓存 支持多线程并发访问 防止内存溢出         socketChannel.pipeline().addLast(                 new ObjectDecoder(1024 * 1024, ClassResolvers                         .weakCachingConcurrentResolver(this.getClass()                                 .getClassLoader())));         // 添加对象编码器 在服务器对外发送消息的时候自动将实现序列化的POJO对象编码         socketChannel.pipeline().addLast(new ObjectEncoder());          socketChannel.pipeline().addLast(new TimeServerHandler());     } }

2.4 TimeServerHandler

package com.netty.server;  import java.util.Calendar; import com.netty.common.RemotingCommand; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler;  /**  * Created by yzy on 2020-11-04  */ public class TimeServerHandler extends SimpleChannelInboundHandler<RemotingCommand> {      @Override     public void channelRead0(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception {        System.out.println("server read " + msg.getCode());       if(msg.getCode() == RemotingCommand.YEAR_REQUEST){           int year = Calendar.getInstance().get(Calendar.YEAR);           RemotingCommand resp = new RemotingCommand();           resp.setBody(year + "年");           ctx.write(resp);       }         if(msg.getCode() == RemotingCommand.DAY_REQUEST){             int day = Calendar.getInstance().get(Calendar.DATE);             RemotingCommand resp = new RemotingCommand();             resp.setBody(day + "日");             ctx.write(resp);         }         if(msg.getCode() == RemotingCommand.MONTH_REQUEST){             int month = Calendar.getInstance().get(Calendar.MONTH) + 1;             RemotingCommand resp = new RemotingCommand();             resp.setBody(month + "月");             ctx.write(resp);         }     }      @Override     public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {         super.channelReadComplete(ctx);         ctx.flush();     }      @Override     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {         super.exceptionCaught(ctx, cause);         ctx.close();     } }

3.客户端代码

3.1 客户端主类

“`
public class ClientMain {
public static void main(String[] args) throws InterruptedException {
TimeClient timeClient = new TimeClient();
//连接服务
timeClient.connet(Config.PORT, Config.IP);
//用户交互
Scanner ip = new Scanner(System.in);;
boolean isExit = false;
while(!isExit){
System.out.println(“请输入 1:获取年 2:获取月 3:获取日 4:退出 “);
int ops = ip.nextInt();
if(ops == 1){
RemotingCommand request = new RemotingCommand();

功能描述 :
客户端通过指令Code获取获取对应的年月日信息

该项目共三个模块
1.common
2.client
3.server

1.公共模块

自定义协议类:

public class RemotingCommand implements Serializable {     public static final int YEAR_REQUEST = 1;     public static final int MONTH_REQUEST = 2;     public static final int DAY_REQUEST = 3;     private int code;     private String body;      public int getCode() {         return code;     }      public void setCode(int code) {         this.code = code;     }      public String getBody() {         return body;     }      public void setBody(String body) {         this.body = body;     } }

2.服务端代码

2.1 服务器启动类

public class ServerMain {     public static void main(String[] args) {         TimeServer timeServer = new TimeServer();         timeServer.bind();     } }

2.2 时间服务器

package com.netty.server;  import java.util.concurrent.ConcurrentHashMap; import com.netty.common.Config; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel;  /**  * Created by yzy on 2020-11-04  */ public class TimeServer {     /** 可以用于保存所有的客户端连接channel , 参考rocketMQ的做法 **/     private final ConcurrentHashMap<String, Channel> clientChannelTable = new ConcurrentHashMap<String, Channel>(5);      public  void bind() {         EventLoopGroup bossEventLoopGroup = new NioEventLoopGroup();         EventLoopGroup workerEventLoopGroup = new NioEventLoopGroup();         try {             ServerBootstrap serverBootstrap = new ServerBootstrap();             serverBootstrap.group(bossEventLoopGroup, workerEventLoopGroup)                     .channel(NioServerSocketChannel.class)                     .option(ChannelOption.SO_BACKLOG, 1024)                     .childHandler(new ServerChannelHandler());              System.out.println("server start");             ChannelFuture channelFuture = serverBootstrap.bind(Config.PORT).sync();             channelFuture.channel().closeFuture().sync();         } catch (InterruptedException e) {             e.printStackTrace();         }finally {             bossEventLoopGroup.shutdownGracefully();             workerEventLoopGroup.shutdownGracefully();         }     } }

2.3 ServerChannelHandler

因为需要序列化RemotingCommand对象, 所以需要引入ObjectEncoder来解决半包粘包的问题

package com.netty.server; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.serialization.ClassResolvers; import io.netty.handler.codec.serialization.ObjectDecoder; import io.netty.handler.codec.serialization.ObjectEncoder;  /**  * Created by yzy on 2020-11-04  */ public class ServerChannelHandler extends ChannelInitializer<SocketChannel> {     @Override     protected void initChannel(SocketChannel socketChannel) throws Exception {         // 添加对象解码器 负责对序列化POJO对象进行解码 设置对象序列化最大长度为1M 防止内存溢出         // 设置线程安全的WeakReferenceMap对类加载器进行缓存 支持多线程并发访问 防止内存溢出         socketChannel.pipeline().addLast(                 new ObjectDecoder(1024 * 1024, ClassResolvers                         .weakCachingConcurrentResolver(this.getClass()                                 .getClassLoader())));         // 添加对象编码器 在服务器对外发送消息的时候自动将实现序列化的POJO对象编码         socketChannel.pipeline().addLast(new ObjectEncoder());          socketChannel.pipeline().addLast(new TimeServerHandler());     } }

2.4 TimeServerHandler

package com.netty.server;  import java.util.Calendar; import com.netty.common.RemotingCommand; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler;  /**  * Created by yzy on 2020-11-04  */ public class TimeServerHandler extends SimpleChannelInboundHandler<RemotingCommand> {      @Override     public void channelRead0(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception {        System.out.println("server read " + msg.getCode());       if(msg.getCode() == RemotingCommand.YEAR_REQUEST){           int year = Calendar.getInstance().get(Calendar.YEAR);           RemotingCommand resp = new RemotingCommand();           resp.setBody(year + "年");           ctx.write(resp);       }         if(msg.getCode() == RemotingCommand.DAY_REQUEST){             int day = Calendar.getInstance().get(Calendar.DATE);             RemotingCommand resp = new RemotingCommand();             resp.setBody(day + "日");             ctx.write(resp);         }         if(msg.getCode() == RemotingCommand.MONTH_REQUEST){             int month = Calendar.getInstance().get(Calendar.MONTH) + 1;             RemotingCommand resp = new RemotingCommand();             resp.setBody(month + "月");             ctx.write(resp);         }     }      @Override     public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {         super.channelReadComplete(ctx);         ctx.flush();     }      @Override     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {         super.exceptionCaught(ctx, cause);         ctx.close();     } }

3.客户端代码

3.1 客户端主类

“`
public class ClientMain {
public static void main(String[] args) throws InterruptedException {
TimeClient timeClient = new TimeClient();
//连接服务
timeClient.connet(Config.PORT, Config.IP);
//用户交互
Scanner ip = new Scanner(System.in);;
boolean isExit = false;
while(!isExit){
System.out.println(“请输入 1:获取年 2:获取月 3:获取日 4:退出 “);
int ops = ip.nextInt();
if(ops == 1){
RemotingCommand request = new RemotingCommand();

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » Netty入门-实现一个时间服务器求职学习资料
分享到: 更多 (0)
D0b2wT.gif

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们