netty4----netty5的客户端和服务端
服务端:
- package com.server;
- import io.netty.bootstrap.ServerBootstrap;
- import io.netty.channel.Channel;
- import io.netty.channel.ChannelFuture;
- import io.netty.channel.ChannelInitializer;
- import io.netty.channel.ChannelOption;
- import io.netty.channel.EventLoopGroup;
- import io.netty.channel.nio.NioEventLoopGroup;
- import io.netty.channel.socket.nio.NioServerSocketChannel;
- import io.netty.handler.codec.string.StringDecoder;
- import io.netty.handler.codec.string.StringEncoder;
- /**
- * netty5版本服务端
- */
- public class Server {
- public static void main(String[] args) {
- //服务类
- ServerBootstrap bootstrap = new ServerBootstrap();
- //boss和worker, netty5不是线程池,而是事件循环组,里面包含线程池。
- EventLoopGroup boss = new NioEventLoopGroup();
- EventLoopGroup worker = new NioEventLoopGroup();
- try {
- //设置线程池
- bootstrap.group(boss, worker);//boss用来监听端口的
- //设置socket工厂、
- bootstrap.channel(NioServerSocketChannel.class);
- //设置管道工厂
- bootstrap.childHandler(new ChannelInitializer<Channel>() {
- @Override
- protected void initChannel(Channel ch) throws Exception {
- ch.pipeline().addLast(new StringDecoder());
- ch.pipeline().addLast(new StringEncoder());
- ch.pipeline().addLast(new ServerHandler());
- }
- });
- //netty3中对应设置如下
- //bootstrap.setOption("backlog", 1024);
- //bootstrap.setOption("tcpNoDelay", true);
- //bootstrap.setOption("keepAlive", true);
- //设置参数,TCP参数
- bootstrap.option(ChannelOption.SO_BACKLOG, 2048);//serverSocketchannel的设置,链接缓冲池的大小。tcp的服务端是有队列的。队列保存2048个客户端。2048后面的连接是拒绝的。
- bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);//socketchannel的设置,维持链接的活跃,清除死链接
- bootstrap.childOption(ChannelOption.TCP_NODELAY, true);//socketchannel的设置,关闭延迟发送。发一包并不是马上发出去,而是积累到一定之后再发出去。
- //绑定端口
- ChannelFuture future = bootstrap.bind(10101);
- System.out.println("start");
- //等待服务端关闭
- future.channel().closeFuture().sync();
- } catch (Exception e) {
- e.printStackTrace();
- } finally{
- //释放资源
- boss.shutdownGracefully();
- worker.shutdownGracefully();
- }
- }
- }
- package com.server;
- import io.netty.channel.ChannelHandlerContext;
- import io.netty.channel.SimpleChannelInboundHandler;
- /**
- * 服务端消息处理
- */
- public class ServerHandler extends SimpleChannelInboundHandler<String> {
- @Override
- protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
- System.out.println(msg);
- ctx.channel().writeAndFlush("hi");
- ctx.writeAndFlush("hi");
- }
- /**
- * 新客户端接入
- */
- @Override
- public void channelActive(ChannelHandlerContext ctx) throws Exception {
- System.out.println("channelActive");
- }
- /**
- * 客户端断开
- */
- @Override
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- System.out.println("channelInactive");
- }
- /**
- * 异常
- */
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
- cause.printStackTrace();
- }
- }
客户端:
- package com.client;
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import io.netty.bootstrap.Bootstrap;
- import io.netty.channel.Channel;
- import io.netty.channel.ChannelFuture;
- import io.netty.channel.ChannelInitializer;
- import io.netty.channel.EventLoopGroup;
- import io.netty.channel.nio.NioEventLoopGroup;
- import io.netty.channel.socket.nio.NioSocketChannel;
- import io.netty.handler.codec.string.StringDecoder;
- import io.netty.handler.codec.string.StringEncoder;
- /**
- * netty5版本的客户端
- */
- public class Client {
- public static void main(String[] args) {
- //服务类
- Bootstrap bootstrap = new Bootstrap();
- //worker
- EventLoopGroup worker = new NioEventLoopGroup();//boss用来监听端口,这里只创建worker
- try {
- //设置线程池
- bootstrap.group(worker);
- //设置socket工厂、
- bootstrap.channel(NioSocketChannel.class);
- //设置管道
- bootstrap.handler(new ChannelInitializer<Channel>() {
- @Override
- protected void initChannel(Channel ch) throws Exception {
- ch.pipeline().addLast(new StringDecoder());
- ch.pipeline().addLast(new StringEncoder());
- ch.pipeline().addLast(new ClientHandler());
- }
- });
- ChannelFuture connect = bootstrap.connect("127.0.0.1", 10101);
- BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
- while(true){
- System.out.println("请输入:");
- String msg = bufferedReader.readLine();
- connect.channel().writeAndFlush(msg);
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally{
- worker.shutdownGracefully();
- }
- }
- }
- package com.client;
- import io.netty.channel.ChannelHandlerContext;
- import io.netty.channel.SimpleChannelInboundHandler;
- /**
- * 客户端消息处理
- */
- public class ClientHandler extends SimpleChannelInboundHandler<String> {
- @Override
- protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
- System.out.println("客户端收到消息:"+msg);
- }
- }
一个客户端启动多个连接:
- package com.client;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.atomic.AtomicInteger;
- import io.netty.bootstrap.Bootstrap;
- import io.netty.channel.Channel;
- import io.netty.channel.ChannelFuture;
- import io.netty.channel.ChannelInitializer;
- import io.netty.channel.EventLoopGroup;
- import io.netty.channel.nio.NioEventLoopGroup;
- import io.netty.channel.socket.nio.NioSocketChannel;
- import io.netty.handler.codec.string.StringDecoder;
- import io.netty.handler.codec.string.StringEncoder;
- /**
- 多连接客户端,客户端保持一个连接不够,要保持多个连接。
- 线程池是有多个线程,每个线程里面有一个任务队列,线程run的时候会从任务队列取一个任务出来,执行任务的run方法,
- 队列里面没有任务就阻塞等待新的任务进来。
- 一个thread + 队列 == 一个单线程线程池 =====> 线程安全的,任务是线性串行执行的
- 对象池:首先初始化n个对象,把这些对象放入一个队列里面,需要对象的时候会出栈一个对象,有对象就出栈,使用完了归还对象池里面。
- 没有对象会阻塞等待有可用的对象。或者创建一个新的对象使用完之后归还线程池,归还的时候如果池子满了就销毁。
- 比如数据库连接池:使用完后要释放资源,就是把连接放回连接池里面。
- 对象组:首先初始化n个对象,把这些对象放入一个数组里面。使用的时候获取一个对象不移除,使用完之后不用归还。需要对象有并发的能力。
- 对象组:线程安全,不会产生阻塞效应
- 对象池:线程不安全,会产生阻塞效应
- */
- public class MultClient {
- /**
- * 服务类
- */
- private Bootstrap bootstrap = new Bootstrap();
- /**
- * 会话,多个channel,
- */
- private List<Channel> channels = new ArrayList<>();
- /**
- * 引用计数
- */
- private final AtomicInteger index = new AtomicInteger();
- /**
- * 初始化
- * @param count
- */
- public void init(int count){
- //worker
- EventLoopGroup worker = new NioEventLoopGroup();
- //设置线程池
- bootstrap.group(worker);
- //设置socket工厂、
- bootstrap.channel(NioSocketChannel.class);
- //设置管道
- bootstrap.handler(new ChannelInitializer<Channel>() {
- @Override
- protected void initChannel(Channel ch) throws Exception {
- ch.pipeline().addLast(new StringDecoder());
- ch.pipeline().addLast(new StringEncoder());
- ch.pipeline().addLast(new ClientHandler());
- }
- });
- for(int i=1; i<=count; i++){
- ChannelFuture future = bootstrap.connect("192.168.0.103", 10101);
- channels.add(future.channel());
- }
- }
- /**
- * 获取会话
- */
- public Channel nextChannel(){
- return getFirstActiveChannel(0);
- }
- private Channel getFirstActiveChannel(int count){
- Channel channel = channels.get(Math.abs(index.getAndIncrement() % channels.size()));
- if(!channel.isActive()){
- //重连
- reconnect(channel);
- if(count >= channels.size()){
- throw new RuntimeException("no can use channel");
- }
- return getFirstActiveChannel(count + 1);
- }
- return channel;
- }
- /**
- * 重连
- * @param channel
- */
- private void reconnect(Channel channel){
- synchronized(channel){
- if(channels.indexOf(channel) == -1){//已经重连过了
- return ;
- }
- Channel newChannel = bootstrap.connect("192.168.0.103", 10101).channel();
- channels.set(channels.indexOf(channel), newChannel);
- }
- }
- }
- package com.client;
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- /**
- * 启动类
- */
- public class Start {
- public static void main(String[] args) {
- MultClient client = new MultClient();
- client.init(5);//初始化5个连接
- BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
- while(true){
- try {
- System.out.println("请输入:");
- String msg = bufferedReader.readLine();
- client.nextChannel().writeAndFlush(msg);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
netty4----netty5的客户端和服务端的更多相关文章
- Netty4 学习笔记之二:客户端与服务端心跳 demo
前言 在上一篇Netty demo 中,了解了Netty中的客户端和服务端之间的通信.这篇则介绍Netty中的心跳. 之前在Mina 中心跳的使用是通过继承 KeepAliveMessageFacto ...
- netty-4.客户端与服务端心跳
(原) 第四篇,客户端与服务端心跳 心跳事件有三种,读空闲,写空闲,读写空闲,定义在了IdleState枚举类中,分别为READER_IDLE,WRITER_IDLE,ALL_IDLE 服务端: ma ...
- java客户端与服务端交互通用处理 框架解析
一.综述 java 客户端与服务端交互过程中,采用NIO通讯是异步的,客户端基本采用同一处理范式,来进行同异步的调用处理. 处理模型有以下几个要素: 1. NIO发送消息后返回的Future 2. 每 ...
- java 从零开始手写 RPC (03) 如何实现客户端调用服务端?
说明 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 写完了客户端和服务端,那么如何实现客户端和服务端的 ...
- TCP学习之五:客户端、服务端异步传输字符串
参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 消息发送接口: 消息接收接口: 客户端: 服务端: 消息发送类: ...
- TCP学习之三:客户端、服务端同步传输字符串
参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 一个客户端.发送一条消息 客户端: 服务端: 注意:Networ ...
- 客户端向服务端传送特殊字符解决方法(检测到有潜在危险的 Request.Form 值)
当客户端向服务端传输特殊字符时报错,错误信息如下图:
- [Java]Hessian客户端和服务端代码例子
简要说明:这是一个比较简单的hessian客户端和服务端,主要实现从客户端发送指定的数据量到服务端,然后服务端在将接收到的数据原封不动返回到客户端.设计该hessian客户端和服务端的初衷是为了做一个 ...
- SignalR 实现web浏览器客户端与服务端的推送功能
SignalR 是一个集成的客户端与服务器库,基于浏览器的客户端和基于 ASP.NET 的服务器组件可以借助它来进行双向多步对话. 换句话说,该对话可不受限制地进行单个无状态请求/响应数据交换:它将继 ...
- Fresco 源码分析(二) Fresco客户端与服务端交互(3) 前后台打通
4.2.1.2.4 PipelineDraweeControllerBuilder.obtainController()源码分析 续 上节中我们提到两个核心的步骤 obtainDataSourceSu ...
随机推荐
- highCharts+Struts2生成柱状图
这篇文章主要结合Struts2+json+Highcharts实现动态数据的显示.为了节省时间,就不写数据库了.在action中用一个集合来模拟从数据库取到的数据.模拟数据为三个学生在不同时间成绩的变 ...
- 2018 ACM-ICPC 北京赛区小结 @ Reconquista
Statistics TYPE: Onsite Contest NAME: 2018 - ICPC Regional - Asia EC - Beijing PLAT: Hihocoder TIME: ...
- 【BZOJ】3300: [USACO2011 Feb]Best Parenthesis(模拟)
http://www.lydsy.com/JudgeOnline/problem.php?id=3300 这个细节太多QAQ 只要将所有的括号'('匹配到下一个')'然后dfs即可 简单吧,,, #i ...
- json DateTime转换
前台: function ChangeDateFormat(jsondate) { jsondate = jsondate.replace("/Date(", "&quo ...
- sql 注入入门
=============安全性篇目录============== 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱,事实上是没机会接触相关 ...
- C# 多线程学习(五)线程同步和冲突解决
from:https://blog.csdn.net/codedoctor/article/details/74358257 首先先说一个线程不同步的例子吧,以下为售票员的模拟售票,多个售票员出售10 ...
- 自定义字体TextView
/** * 备注: * 作者:王莹 * 时间:2017/5/4. * ~_~想睡觉了!! * (-o-)~zZ我想睡啦- * π_π?打瞌睡 */ public class FontsTextView ...
- Duilib教程-自动布局3-分隔条
先看一个常用的图,如下: 左边是导航栏,右边是信息区. 中间可以自由拉伸. XML如下: <?xml version="1.0" encoding="utf-8&q ...
- 160718、jsoup-1.8.1.jar操作html
导入jsoup-1.8.1.jarimport java.io.IOException;import org.jsoup.Connection;import org.jsoup.Jsoup;impor ...
- 巨蟒python全栈开发flask9 项目开始1
1.项目需求分析 立项:Javis&&taisen(三个月全部,先模拟出一个玩具,硬件需要周期长一些) 想法 --- 需求分析: .通过玩具与孩子实时进行沟通 .希望玩具的知识渊博 . ...