服务端:

  1. package com.server;
  2.  
  3. import io.netty.bootstrap.ServerBootstrap;
  4. import io.netty.channel.Channel;
  5. import io.netty.channel.ChannelFuture;
  6. import io.netty.channel.ChannelInitializer;
  7. import io.netty.channel.ChannelOption;
  8. import io.netty.channel.EventLoopGroup;
  9. import io.netty.channel.nio.NioEventLoopGroup;
  10. import io.netty.channel.socket.nio.NioServerSocketChannel;
  11. import io.netty.handler.codec.string.StringDecoder;
  12. import io.netty.handler.codec.string.StringEncoder;
  13.  
  14. /**
  15. * netty5版本服务端
  16. */
  17. public class Server {
  18.  
  19. public static void main(String[] args) {
  20. //服务类
  21. ServerBootstrap bootstrap = new ServerBootstrap();
  22.  
  23. //boss和worker, netty5不是线程池,而是事件循环组,里面包含线程池。
  24. EventLoopGroup boss = new NioEventLoopGroup();
  25. EventLoopGroup worker = new NioEventLoopGroup();
  26.  
  27. try {
  28. //设置线程池
  29. bootstrap.group(boss, worker);//boss用来监听端口的
  30.  
  31. //设置socket工厂、
  32. bootstrap.channel(NioServerSocketChannel.class);
  33.  
  34. //设置管道工厂
  35. bootstrap.childHandler(new ChannelInitializer<Channel>() {
  36.  
  37. @Override
  38. protected void initChannel(Channel ch) throws Exception {
  39. ch.pipeline().addLast(new StringDecoder());
  40. ch.pipeline().addLast(new StringEncoder());
  41. ch.pipeline().addLast(new ServerHandler());
  42. }
  43. });
  44.  
  45. //netty3中对应设置如下
  46. //bootstrap.setOption("backlog", 1024);
  47. //bootstrap.setOption("tcpNoDelay", true);
  48. //bootstrap.setOption("keepAlive", true);
  49. //设置参数,TCP参数
  50. bootstrap.option(ChannelOption.SO_BACKLOG, 2048);//serverSocketchannel的设置,链接缓冲池的大小。tcp的服务端是有队列的。队列保存2048个客户端。2048后面的连接是拒绝的。
  51. bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);//socketchannel的设置,维持链接的活跃,清除死链接
  52. bootstrap.childOption(ChannelOption.TCP_NODELAY, true);//socketchannel的设置,关闭延迟发送。发一包并不是马上发出去,而是积累到一定之后再发出去。
  53.  
  54. //绑定端口
  55. ChannelFuture future = bootstrap.bind(10101);
  56.  
  57. System.out.println("start");
  58.  
  59. //等待服务端关闭
  60. future.channel().closeFuture().sync();
  61.  
  62. } catch (Exception e) {
  63. e.printStackTrace();
  64. } finally{
  65. //释放资源
  66. boss.shutdownGracefully();
  67. worker.shutdownGracefully();
  68. }
  69. }
  70. }
  1. package com.server;
  2.  
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.SimpleChannelInboundHandler;
  5. /**
  6. * 服务端消息处理
  7. */
  8. public class ServerHandler extends SimpleChannelInboundHandler<String> {
  9.  
  10. @Override
  11. protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
  12. System.out.println(msg);
  13. ctx.channel().writeAndFlush("hi");
  14. ctx.writeAndFlush("hi");
  15. }
  16.  
  17. /**
  18. * 新客户端接入
  19. */
  20. @Override
  21. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  22. System.out.println("channelActive");
  23. }
  24.  
  25. /**
  26. * 客户端断开
  27. */
  28. @Override
  29. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
  30. System.out.println("channelInactive");
  31. }
  32.  
  33. /**
  34. * 异常
  35. */
  36. @Override
  37. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  38. cause.printStackTrace();
  39. }
  40.  
  41. }

客户端:

  1. package com.client;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.InputStreamReader;
  5.  
  6. import io.netty.bootstrap.Bootstrap;
  7. import io.netty.channel.Channel;
  8. import io.netty.channel.ChannelFuture;
  9. import io.netty.channel.ChannelInitializer;
  10. import io.netty.channel.EventLoopGroup;
  11. import io.netty.channel.nio.NioEventLoopGroup;
  12. import io.netty.channel.socket.nio.NioSocketChannel;
  13. import io.netty.handler.codec.string.StringDecoder;
  14. import io.netty.handler.codec.string.StringEncoder;
  15.  
  16. /**
  17. * netty5版本的客户端
  18. */
  19. public class Client {
  20.  
  21. public static void main(String[] args) {
  22. //服务类
  23. Bootstrap bootstrap = new Bootstrap();
  24. //worker
  25. EventLoopGroup worker = new NioEventLoopGroup();//boss用来监听端口,这里只创建worker
  26. try {
  27. //设置线程池
  28. bootstrap.group(worker);
  29. //设置socket工厂、
  30. bootstrap.channel(NioSocketChannel.class);
  31. //设置管道
  32. bootstrap.handler(new ChannelInitializer<Channel>() {
  33. @Override
  34. protected void initChannel(Channel ch) throws Exception {
  35. ch.pipeline().addLast(new StringDecoder());
  36. ch.pipeline().addLast(new StringEncoder());
  37. ch.pipeline().addLast(new ClientHandler());
  38. }
  39. });
  40. ChannelFuture connect = bootstrap.connect("127.0.0.1", 10101);
  41. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
  42. while(true){
  43. System.out.println("请输入:");
  44. String msg = bufferedReader.readLine();
  45. connect.channel().writeAndFlush(msg);
  46. }
  47. } catch (Exception e) {
  48. e.printStackTrace();
  49. } finally{
  50. worker.shutdownGracefully();
  51. }
  52. }
  53. }
  1. package com.client;
  2.  
  3. import io.netty.channel.ChannelHandlerContext;
  4. import io.netty.channel.SimpleChannelInboundHandler;
  5. /**
  6. * 客户端消息处理
  7. */
  8. public class ClientHandler extends SimpleChannelInboundHandler<String> {
  9. @Override
  10. protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
  11. System.out.println("客户端收到消息:"+msg);
  12. }
  13.  
  14. }

一个客户端启动多个连接:

  1. package com.client;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import java.util.concurrent.atomic.AtomicInteger;
  6.  
  7. import io.netty.bootstrap.Bootstrap;
  8. import io.netty.channel.Channel;
  9. import io.netty.channel.ChannelFuture;
  10. import io.netty.channel.ChannelInitializer;
  11. import io.netty.channel.EventLoopGroup;
  12. import io.netty.channel.nio.NioEventLoopGroup;
  13. import io.netty.channel.socket.nio.NioSocketChannel;
  14. import io.netty.handler.codec.string.StringDecoder;
  15. import io.netty.handler.codec.string.StringEncoder;
  16.  
  17. /**
  18. 多连接客户端,客户端保持一个连接不够,要保持多个连接。
  19.  
  20. 线程池是有多个线程,每个线程里面有一个任务队列,线程run的时候会从任务队列取一个任务出来,执行任务的run方法,
  21. 队列里面没有任务就阻塞等待新的任务进来。
  22.  
  23. 一个thread + 队列 == 一个单线程线程池 =====> 线程安全的,任务是线性串行执行的
  24.  
  25. 对象池:首先初始化n个对象,把这些对象放入一个队列里面,需要对象的时候会出栈一个对象,有对象就出栈,使用完了归还对象池里面。
  26. 没有对象会阻塞等待有可用的对象。或者创建一个新的对象使用完之后归还线程池,归还的时候如果池子满了就销毁。
  27. 比如数据库连接池:使用完后要释放资源,就是把连接放回连接池里面。
  28.  
  29. 对象组:首先初始化n个对象,把这些对象放入一个数组里面。使用的时候获取一个对象不移除,使用完之后不用归还。需要对象有并发的能力。
  30.  
  31. 对象组:线程安全,不会产生阻塞效应
  32. 对象池:线程不安全,会产生阻塞效应
  33. */
  34. public class MultClient {
  35.  
  36. /**
  37. * 服务类
  38. */
  39. private Bootstrap bootstrap = new Bootstrap();
  40.  
  41. /**
  42. * 会话,多个channel,
  43. */
  44. private List<Channel> channels = new ArrayList<>();
  45.  
  46. /**
  47. * 引用计数
  48. */
  49. private final AtomicInteger index = new AtomicInteger();
  50.  
  51. /**
  52. * 初始化
  53. * @param count
  54. */
  55. public void init(int count){
  56.  
  57. //worker
  58. EventLoopGroup worker = new NioEventLoopGroup();
  59.  
  60. //设置线程池
  61. bootstrap.group(worker);
  62.  
  63. //设置socket工厂、
  64. bootstrap.channel(NioSocketChannel.class);
  65.  
  66. //设置管道
  67. bootstrap.handler(new ChannelInitializer<Channel>() {
  68.  
  69. @Override
  70. protected void initChannel(Channel ch) throws Exception {
  71. ch.pipeline().addLast(new StringDecoder());
  72. ch.pipeline().addLast(new StringEncoder());
  73. ch.pipeline().addLast(new ClientHandler());
  74. }
  75. });
  76.  
  77. for(int i=1; i<=count; i++){
  78. ChannelFuture future = bootstrap.connect("192.168.0.103", 10101);
  79. channels.add(future.channel());
  80. }
  81. }
  82.  
  83. /**
  84. * 获取会话
  85. */
  86. public Channel nextChannel(){
  87. return getFirstActiveChannel(0);
  88. }
  89.  
  90. private Channel getFirstActiveChannel(int count){
  91. Channel channel = channels.get(Math.abs(index.getAndIncrement() % channels.size()));
  92. if(!channel.isActive()){
  93. //重连
  94. reconnect(channel);
  95. if(count >= channels.size()){
  96. throw new RuntimeException("no can use channel");
  97. }
  98. return getFirstActiveChannel(count + 1);
  99. }
  100. return channel;
  101. }
  102.  
  103. /**
  104. * 重连
  105. * @param channel
  106. */
  107. private void reconnect(Channel channel){
  108. synchronized(channel){
  109. if(channels.indexOf(channel) == -1){//已经重连过了
  110. return ;
  111. }
  112. Channel newChannel = bootstrap.connect("192.168.0.103", 10101).channel();
  113. channels.set(channels.indexOf(channel), newChannel);
  114. }
  115. }
  116. }
  1. package com.client;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.InputStreamReader;
  5. /**
  6. * 启动类
  7. */
  8. public class Start {
  9.  
  10. public static void main(String[] args) {
  11.  
  12. MultClient client = new MultClient();
  13. client.init(5);//初始化5个连接
  14. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
  15. while(true){
  16. try {
  17. System.out.println("请输入:");
  18. String msg = bufferedReader.readLine();
  19. client.nextChannel().writeAndFlush(msg);
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. }
  25.  
  26. }

netty4----netty5的客户端和服务端的更多相关文章

  1. Netty4 学习笔记之二:客户端与服务端心跳 demo

    前言 在上一篇Netty demo 中,了解了Netty中的客户端和服务端之间的通信.这篇则介绍Netty中的心跳. 之前在Mina 中心跳的使用是通过继承 KeepAliveMessageFacto ...

  2. netty-4.客户端与服务端心跳

    (原) 第四篇,客户端与服务端心跳 心跳事件有三种,读空闲,写空闲,读写空闲,定义在了IdleState枚举类中,分别为READER_IDLE,WRITER_IDLE,ALL_IDLE 服务端: ma ...

  3. java客户端与服务端交互通用处理 框架解析

    一.综述 java 客户端与服务端交互过程中,采用NIO通讯是异步的,客户端基本采用同一处理范式,来进行同异步的调用处理. 处理模型有以下几个要素: 1. NIO发送消息后返回的Future 2. 每 ...

  4. java 从零开始手写 RPC (03) 如何实现客户端调用服务端?

    说明 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 写完了客户端和服务端,那么如何实现客户端和服务端的 ...

  5. TCP学习之五:客户端、服务端异步传输字符串

    参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 消息发送接口: 消息接收接口: 客户端: 服务端: 消息发送类: ...

  6. TCP学习之三:客户端、服务端同步传输字符串

    参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 一个客户端.发送一条消息 客户端: 服务端: 注意:Networ ...

  7. 客户端向服务端传送特殊字符解决方法(检测到有潜在危险的 Request.Form 值)

    当客户端向服务端传输特殊字符时报错,错误信息如下图:

  8. [Java]Hessian客户端和服务端代码例子

    简要说明:这是一个比较简单的hessian客户端和服务端,主要实现从客户端发送指定的数据量到服务端,然后服务端在将接收到的数据原封不动返回到客户端.设计该hessian客户端和服务端的初衷是为了做一个 ...

  9. SignalR 实现web浏览器客户端与服务端的推送功能

    SignalR 是一个集成的客户端与服务器库,基于浏览器的客户端和基于 ASP.NET 的服务器组件可以借助它来进行双向多步对话. 换句话说,该对话可不受限制地进行单个无状态请求/响应数据交换:它将继 ...

  10. Fresco 源码分析(二) Fresco客户端与服务端交互(3) 前后台打通

    4.2.1.2.4 PipelineDraweeControllerBuilder.obtainController()源码分析 续 上节中我们提到两个核心的步骤 obtainDataSourceSu ...

随机推荐

  1. highCharts+Struts2生成柱状图

    这篇文章主要结合Struts2+json+Highcharts实现动态数据的显示.为了节省时间,就不写数据库了.在action中用一个集合来模拟从数据库取到的数据.模拟数据为三个学生在不同时间成绩的变 ...

  2. 2018 ACM-ICPC 北京赛区小结 @ Reconquista

    Statistics TYPE: Onsite Contest NAME: 2018 - ICPC Regional - Asia EC - Beijing PLAT: Hihocoder TIME: ...

  3. 【BZOJ】3300: [USACO2011 Feb]Best Parenthesis(模拟)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3300 这个细节太多QAQ 只要将所有的括号'('匹配到下一个')'然后dfs即可 简单吧,,, #i ...

  4. json DateTime转换

    前台: function ChangeDateFormat(jsondate) { jsondate = jsondate.replace("/Date(", "&quo ...

  5. sql 注入入门

    =============安全性篇目录============== 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱,事实上是没机会接触相关 ...

  6. C# 多线程学习(五)线程同步和冲突解决

    from:https://blog.csdn.net/codedoctor/article/details/74358257 首先先说一个线程不同步的例子吧,以下为售票员的模拟售票,多个售票员出售10 ...

  7. 自定义字体TextView

    /** * 备注: * 作者:王莹 * 时间:2017/5/4. * ~_~想睡觉了!! * (-o-)~zZ我想睡啦- * π_π?打瞌睡 */ public class FontsTextView ...

  8. Duilib教程-自动布局3-分隔条

    先看一个常用的图,如下: 左边是导航栏,右边是信息区. 中间可以自由拉伸. XML如下: <?xml version="1.0" encoding="utf-8&q ...

  9. 160718、jsoup-1.8.1.jar操作html

    导入jsoup-1.8.1.jarimport java.io.IOException;import org.jsoup.Connection;import org.jsoup.Jsoup;impor ...

  10. 巨蟒python全栈开发flask9 项目开始1

    1.项目需求分析 立项:Javis&&taisen(三个月全部,先模拟出一个玩具,硬件需要周期长一些) 想法 --- 需求分析: .通过玩具与孩子实时进行沟通 .希望玩具的知识渊博 . ...