netty官网:点击进入

学习netty之实现一个丢弃服务器

环境:

  • JDK1.8
  • netty5.0+

步骤:

  1. 实现一个丢弃服务器
  2. 实现一个客户端发送数据

丢弃服务器的创建

//用于接受客户端的的连接,将连接注册到worker中
EventLoopGroup boos = new NioEventLoopGroup(); //处理客户端的连接
EventLoopGroup worker = new NioEventLoopGroup(); //服务端启动类
ServerBootstrap serverBootstrap = new ServerBootstrap(); ChannelFuture sync = null;
try {
ServerBootstrap boot = serverBootstrap.group(boos, worker)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//自己继承了ChannelHandlerAdapter
ch.pipeline().addLast(new DiscardHandler());
}
});
//绑定端口,接受连接
sync = boot.bind(10980).sync();
System.out.println("丢弃服务器启动...");
//等待服务器关闭
sync.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
if(null != sync){
try {
//管理连接
sync.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//处理完客户端的请求后在优雅的关闭
boos.shutdownGracefully();
worker.shutdownGracefully();
} 

DiscardHandler实现:

    public class DiscardHandler extends ChannelHandlerAdapter {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("客户端断开连接");
ctx.writeAndFlush(Unpooled.copiedBuffer("有一个客户端断开连接".getBytes("UTF-8")));
cause.printStackTrace();
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
服务器端本地查看发送来的信息
ByteBuf msg1 = (ByteBuf) msg;
byte[] buf = new byte[msg1.readableBytes()];
msg1.readBytes(buf);
String s = new String(buf, "UTF-8");
System.out.println("客户端发来的信息:"+s);
//直接丢弃信息
ReferenceCountUtil.release(msg);
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer("---连接成功:",CharsetUtil.UTF_8));
}
}

客户端发送数据:

           NioEventLoopGroup clientGroup = null;
try {
clientGroup = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
ChannelFuture connect = bootstrap.group(clientGroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//自定义客户端的发送逻辑
ch.pipeline().addLast(new ClientHandler());
}
})
.connect("localhost", 10980);
while (true) {
Scanner scanner = new Scanner(System.in);
System.out.println("输入 exit 结束:");
String s = scanner.nextLine(); if (!Objects.isNull(s) && s.equals("exit")) {
connect.channel().writeAndFlush(Unpooled.copiedBuffer(s.getBytes("UTF-8")))
//关闭监听器,代表ChannelFuture执行返回后,关闭连接。
.addListener(ChannelFutureListener.CLOSE);
break;
}
connect.channel().writeAndFlush(Unpooled
.copiedBuffer(s.getBytes("UTF-8")));
}
}catch (UnsupportedEncodingException e) {
e.printStackTrace();
} finally {
clientGroup.shutdownGracefully();
}
}

ClientHandler实现:

    public class ClientHandler extends ChannelHandlerAdapter {

    @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf msg1 = (ByteBuf) msg;
byte[] buf = new byte[msg1.readableBytes()];
msg1.readBytes(buf);
System.out.println("服务器返回的信息:"+new String(buf,"UTF-8"));
//释放内存
ReferenceCountUtil.release(msg); } @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
System.out.println(cause.getMessage());
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer("HI 首次连接".getBytes("UTF-8")));
} @Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
System.out.println("数据发送成功");
} }

问题:

开始是继承了SimpleChannleINBoundAdpater<ByteBuf>
    在channelReadComplete中 发送 ctx.writeAndFlush()中发送服务器,会造成死循环,客户端一直发送信息给服务器,造成资源浪费
    其次,在发发送数据的时候直接发送ByteBuf对象,客户端是无法接受到的需要转换成
    Unpooled.copiedBuffer(byte[]);    发送数据

PS:

可以实现在线用户数量梳理:    
    在服务端初始化一个AtomicInteger类,每次客户端连接的时候将此数值原子性+1,
    在客户端断开的时候将其-1.每个用户连接后,将其信息发送出去。

netty初试的更多相关文章

  1. 记录初试Netty(2)-服务端心跳检测

    今天在在搭建的netty框架中添加心跳机制,特此记录一下:      1.什么是心跳机制? 心跳是在TCP长连接中,客户端和服务端定时向对方发送数据包通知对方自己还在线,保证连接的有效性的一种机制 在 ...

  2. 谈谈如何使用Netty开发实现高性能的RPC服务器

    RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...

  3. 基于netty http协议栈的轻量级流程控制组件的实现

    今儿个是冬至,所谓“冬大过年”,公司也应景五点钟就放大伙儿回家吃饺子喝羊肉汤了,而我本着极高的职业素养依然坚持留在公司(实则因为没饺子吃没羊肉汤喝,只能呆公司吃食堂……).趁着这一个多小时的时间,想跟 ...

  4. 从netty-example分析Netty组件续

    上文我们从netty-example的Discard服务器端示例分析了netty的组件,今天我们从另一个简单的示例Echo客户端分析一下上个示例中没有出现的netty组件. 1. 服务端的连接处理,读 ...

  5. 源码分析netty服务器创建过程vs java nio服务器创建

    1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...

  6. 从netty-example分析Netty组件

    分析netty从源码开始 准备工作: 1.下载源代码:https://github.com/netty/netty.git 我下载的版本为4.1 2. eclipse导入maven工程. netty提 ...

  7. Netty实现高性能RPC服务器优化篇之消息序列化

    在本人写的前一篇文章中,谈及有关如何利用Netty开发实现,高性能RPC服务器的一些设计思路.设计原理,以及具体的实现方案(具体参见:谈谈如何使用Netty开发实现高性能的RPC服务器).在文章的最后 ...

  8. Netty构建分布式消息队列(AvatarMQ)设计指南之架构篇

    目前业界流行的分布式消息队列系统(或者可以叫做消息中间件)种类繁多,比如,基于Erlang的RabbitMQ.基于Java的ActiveMQ/Apache Kafka.基于C/C++的ZeroMQ等等 ...

  9. 基于Netty打造RPC服务器设计经验谈

    自从在园子里,发表了两篇如何基于Netty构建RPC服务器的文章:谈谈如何使用Netty开发实现高性能的RPC服务器.Netty实现高性能RPC服务器优化篇之消息序列化 之后,收到了很多同行.园友们热 ...

随机推荐

  1. spring注解简单记录

    @Autowired 自动匹配,按类型 @qualifiter("beanname") 当有多个bean匹配时,可指定bean名称 @Resource byname优先匹配,然后b ...

  2. 2018-2019-2 网络对抗技术 20165317 Exp5 MSF基础应用

    2018-2019-2 网络对抗技术 20165317 Exp5 MSF基础应用 一.原理与实践说明 1.实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具 ...

  3. linux基础命令--groupmod 修改组定义

    描述 groupmod命令用于修改系统上的组定义. groupmod命令通过更改组数据库(the group database)里的相关条目来修改指定的组. 语法 groupmod [选项] GROU ...

  4. Mybatis-Plus 3.0代码生成器

    package com.kyplatform.generator; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusExcepti ...

  5. 2016(4)数据库系统,ER模型,规范化理论,并发控制

    试题四(共25分) 阅读以下关于数据库设计的叙述,在答题纸上回答问题1至问题3. 某航空公司要开发一个订票信息处理系统,以方便各个代理商销售机票.开发小组经过设计,给出该系统的部分关系模式如下: 航班 ...

  6. 连接H3C交换机的Console口连不上

    一.故障:使用Console线连接交换机的Console口连不上. 处理步骤: 1.先把Console线连接好,一端连接交换机的Console口,另一端连接电脑的USB口. 2.安装Console线驱 ...

  7. JMeter-性能测试监控(解决.sh文件的启动)

    下载插件 https://jmeter-plugins.org/downloads/old/ 已安装了jmeter-plugins-manager,装的这个不知道生没生效.... 2.问题:启动就显示 ...

  8. 使用dbms_profiler收集存储过程每步执行时间

    最近和优化团队的专家学到一个很有意义的内置包:dbms_profiler,专门用于分析Oracle存储过程中的各段代码的时间开销情况,从而快速找到性能瓶颈的步骤. 1.sys创建dbms_profil ...

  9. springMVC--annotation

    一 解析类 ComponentScanBeanDefinitionParser component-scan标签解析类 component-scan 兼容 annotation-config ,因此前 ...

  10. (.NET高级课程笔记)泛型总结

    泛型总结 1.引入泛型:延迟声明,即在声明的时候没有指定参数类型,只有当调用的时候才会确定 其参数类型(架构师的理念:推迟一切可以推迟的) 2.如何声明和使用泛型 3.泛型的好处和原理 4.泛型类.泛 ...