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. [04-05]box框模型(Box Model)定义了元素框处理元素内容、内边距、边框和外边距的方式

    实际占有的宽 = width + 2padding(内边距) + 2border(边框) + 2margin(外边距) 实际占有的高 = height + 2padding + 2border + 2 ...

  2. django的闪现和增、删、改、查

    使用 messages 闪现在views.py中导入 from django.contrib import messages 在html中 {% if messages %} {% for mess ...

  3. MySQL执行计划复习

    MySQL执行计划分析 Ⅰ.认识执行计划的每个字段 (root@localhost) [(none)]> desc select 1; +----+-------------+-------+- ...

  4. sqlmap tamper下模块的使用

    使用方法 根据实际情况,可以同时使用多个脚本,使用-v参数可以看到payload的变化. sqlmap.py -u "http://www.target.com/test.php?id=12 ...

  5. 转:三款免费好用的Gif录屏神器

    原文链接:三款免费好用的Gif录屏神器 自己用了      ScreenToGif 版本2.14.1下载地址 原文内容: 三款免费好用的Gif录屏神器 2018年06月02日 18:52:21 独家雨 ...

  6. Python_tkinter(5)_GUI工具

    1.Excel行数统计工具 源代码 import xlrd import tkinter as tk import tkinter.filedialog # 计算一个工作簿中所有Sheet表的行数 d ...

  7. python条件表达式:多项分支,双向分支

    # ### 多项分支 ''' if 条件表达式1: code1 code2 elif 条件表达式2: code3 code4 elif 条件表达式3: code5 code6 else: code7 ...

  8. U盘安装Windows原版系统(安装方式有很多,我讲我的安装方式)

    我陈某人,也是安装过至少200部台式或笔记本的人物. 低调,低调,开个玩笑~ 安装方式有很多,我讲我的安装方式,欢迎收藏. 1.下载准备文件下载.iso原版系统镜像文件http://msdn.itel ...

  9. Java基础(面试题)

    1:面向对象编程有很多重要的特性: 封装,继承,多态和抽象. 2:什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? (1)Java虚拟机是一个可以执行Java字节码的虚拟机进程.J ...

  10. Qt QLineEdit 漂亮的搜索框 && 密码模式 && 格式化输入 && 提示文字 && 选择内容并移动 && 清除全部输入

    先上一个漂亮的搜索框效果图, 输入搜索文本效果, 点击搜索图标效果: //实现代码 void MainWindow::iniLineEdit() { ui->lineEdit->setPl ...