【Netty】Netty的Hello World程序之Discard Server
一、有关Discard Server的说明
世界上最简单的协议(程序)不是“Hello, World!”而是Discard(丢弃)。它是一种丢弃任何接收到的数据而没有任何响应的协议。
要实现丢弃协议,惟一需要做的就是忽略所有接收到的数据。让我们直接从处理程序实现开始,它处理由Netty生成的I/O事件
二、Discard Server的实现代码
package com.zbq.simpledemo.demo1; import io.netty.bootstrap.ServerBootstrap;
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.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel; /**
* 丢弃任何进入的数据 启动服务端的DiscardServerHandler
*/
public class DiscardServer {
private int port; public DiscardServer(int port) {
super();
this.port = port;
} public void run() throws Exception { /***
* NioEventLoopGroup 是用来处理I/O操作的多线程事件循环器,
* Netty提供了许多不同的EventLoopGroup的实现用来处理不同传输协议。 在这个例子中我们实现了一个服务端的应用,
* 因此会有2个NioEventLoopGroup会被使用。 第一个经常被叫做‘boss’,用来接收进来的连接。
* 第二个经常被叫做‘worker’,用来处理已经被接收的连接, 一旦‘boss’接收到连接,就会把连接信息注册到‘worker’上。
* 如何知道多少个线程已经被使用,如何映射到已经创建的Channels上都需要依赖于EventLoopGroup的实现,
* 并且可以通过构造函数来配置他们的关系。
*/
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
System.out.println("准备运行端口:" + port);
try {
/**
* ServerBootstrap 是一个启动NIO服务的辅助启动类 你可以在这个服务中直接使用Channel
*/
ServerBootstrap b = new ServerBootstrap();
/**
* 这一步是必须的,如果没有设置group将会报java.lang.IllegalStateException: group not
* set异常
*/
b = b.group(bossGroup, workerGroup);
/***
* ServerSocketChannel以NIO的selector为基础进行实现的,用来接收新的连接
* 这里告诉Channel如何获取新的连接.
*/
b = b.channel(NioServerSocketChannel.class);
/***
* 这里的事件处理类经常会被用来处理一个最近的已经接收的Channel。 ChannelInitializer是一个特殊的处理类,
* 他的目的是帮助使用者配置一个新的Channel。
* 也许你想通过增加一些处理类比如NettyServerHandler来配置一个新的Channel
* 或者其对应的ChannelPipeline来实现你的网络程序。 当你的程序变的复杂时,可能你会增加更多的处理类到pipline上,
* 然后提取这些匿名类到最顶层的类上。
*/
b = b.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new DiscardServerHandler());// demo1.discard
// ch.pipeline().addLast(new
// ResponseServerHandler());//demo2.echo
// ch.pipeline().addLast(new
// TimeServerHandler());//demo3.time
}
});
/***
* 你可以设置这里指定的通道实现的配置参数。 我们正在写一个TCP/IP的服务端,
* 因此我们被允许设置socket的参数选项比如tcpNoDelay和keepAlive。
* 请参考ChannelOption和详细的ChannelConfig实现的接口文档以此可以对ChannelOptions的有一个大概的认识。
*/
b = b.option(ChannelOption.SO_BACKLOG, 128);
/***
* option()是提供给NioServerSocketChannel用来接收进来的连接。
* childOption()是提供给由父管道ServerChannel接收到的连接,
* 在这个例子中也是NioServerSocketChannel。
*/
b = b.childOption(ChannelOption.SO_KEEPALIVE, true);
/***
* 绑定端口并启动去接收进来的连接
*/
ChannelFuture f = b.bind(port).sync();
/**
* 这里会一直等待,直到socket被关闭
*/
f.channel().closeFuture().sync();
} finally {
/***
* 关闭
*/
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
} //将规则跑起来
public static void main(String[] args) throws Exception {
int port;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
} else {
port = 8080;
}
new DiscardServer(port).run();
System.out.println("server:run()");
}
}
package com.zbq.simpledemo.demo1; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil; /**
* 服务端处理通道.这里只是打印一下请求的内容,并不对请求进行任何的响应 DiscardServerHandler 继承自
* ChannelHandlerAdapter, 这个类实现了ChannelHandler接口, ChannelHandler提供了许多事件处理的接口方法,
* 然后你可以覆盖这些方法。 现在仅仅只需要继承ChannelHandlerAdapter类而不是你自己去实现接口方法。
*
*/
public class DiscardServerHandler extends ChannelHandlerAdapter {
/**
* 这里我们覆盖了chanelRead()事件处理方法。 每当从客户端收到新的数据时, 这个方法会在收到消息时被调用,
* 这个例子中,收到的消息的类型是ByteBuf
*
* @param ctx
* 通道处理的上下文信息
* @param msg
* 接收的消息
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) { try {
ByteBuf in = (ByteBuf) msg;
// 打印客户端输入,传输过来的的字符
System.out.print(in.toString(CharsetUtil.UTF_8));
} finally {
/**
* ByteBuf是一个引用计数对象,这个对象必须显示地调用release()方法来释放。
* 请记住处理器的职责是释放所有传递到处理器的引用计数对象。
*/
// 抛弃收到的数据
ReferenceCountUtil.release(msg);
} } /***
* 这个方法会在发生异常时触发
*
* @param ctx
* @param cause
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
/**
* exceptionCaught() 事件处理方法是当出现 Throwable 对象才会被调用,即当 Netty 由于 IO
* 错误或者处理器在处理事件时抛出的异常时。在大部分情况下,捕获的异常应该被记录下来 并且把关联的 channel
* 给关闭掉。然而这个方法的处理方式会在遇到不同异常的情况下有不 同的实现,比如你可能想在关闭连接之前发送一个错误码的响应消息。
*/
// 出现异常就关闭
cause.printStackTrace();
ctx.close();
} }
三、运行main方法,启动Discard Server程序
四、通过 telnet,访问Discard Server程序
客户端访问
* 打开命令行窗口,键入 telnet 127.0.0.1 8080 回车,进入telnet 终端
* 然后随便输入回车,服务端就会打印你输入的数据
【Netty】Netty的Hello World程序之Discard Server的更多相关文章
- 构建基于Netty 的HTTP/HTTPS 应用程序
HTTP/HTTPS是最常见的协议套件之一,并且随着智能手机的成功,它的应用也日益广泛,因为对于任何公司来说,拥有一个可以被移动设备访问的网站几乎是必须的.这些协议也被用于其他方面.许多组织导出的用于 ...
- [Netty] - Netty IN ACTION(导言)
最近没什么事儿做,刚好看到有需要网络编程的知识,java中有NIO和IO两种不同的方式,但是NIO的编写比较麻烦,刚好找到一个成熟的网络框架Netty.接下来的一个月就准备将Netty IN ACTI ...
- Writing a Discard Server 写个抛弃服务器 世上最简单的协议
Netty.docs: User guide for 4.x https://netty.io/wiki/user-guide-for-4.x.html The most simplistic pro ...
- 用开源 ASP.NET MVC 程序 Bonobo Git Server 搭建 Git 服务器(转)
用开源 ASP.NET MVC 程序 Bonobo Git Server 搭建 Git 服务器 现在不用Git,都不好意思说自己是程序员. 当你想用Git,而源代码服务器是Windows系统时,你 ...
- 应用程序中的server错误,没有名称为“ServiceBehavior”的服务行为
应用程序中的server错误,没有名称为"ServiceBehavior"的服务行为 今天在阅读"创建和使用Web服务"的相关内容,在浏览器中查 ...
- [Netty] - Netty入门(最简单的Netty客户端/服务器程序)
Java中的NIO是一种解决阻塞式IO问题的基本技术,但是NIO的编写对java程序员是有比较高的要求的.那么Netty就是一种简化操作的一个成熟的网络IO编程框架.这里简单介绍一个程序,代码是< ...
- Netty 超时机制及心跳程序实现
Netty 超时机制的介绍 Netty 的超时类型 IdleState 主要分为: ALL_IDLE : 一段时间内没有数据接收或者发送 READER_IDLE : 一段时间内没有数据接收 WRITE ...
- netty使用以及聊天小程序
<从零开始搭建游戏服务器>Netty导入创建Socket服务器 Netty入门教程 Netty 聊天小程序
- Netty 框架学习 —— 基于 Netty 的 HTTP/HTTPS 应用程序
通过 SSL/TLS 保护应用程序 SSL 和 TLS 安全协议层叠在其他协议之上,用以实现数据安全.为了支持 SSL/TLS,Java 提供了 javax.net.ssl 包,它的 SSLConte ...
随机推荐
- 安装Visual Studio IntelliCode提供代码智能提示AI
The Visual Studio IntelliCode extension provides AI-assisted development features for Python, TypeSc ...
- Spring Boot 知识笔记(servlet、监听器、拦截器)
一.通过注解自定义servlet package net.Eleven.demo.servlet; import javax.servlet.ServletException; import java ...
- 第02组 Alpha冲刺(2/6)
队名:無駄無駄 组长博客 作业博客 组员情况 张越洋 过去两天完成了哪些任务 任务分配.进度监督 提交记录(全组共用) 接下来的计划 沟通前后端成员,监督.提醒他们尽快完成各自的进度 还剩下哪些任务 ...
- JavaScript 一些实用技巧
快速创建从0到n的数字 let arr1 = [...(new Array(n)).keys()]; let arr2 = Array.from({length:n},(v, k) => k); ...
- kube-prometheus部署
一.从git拉取相应yaml文件 git clone https://github.com/coreos/kube-prometheus.git 二.修改grafana及prometheus的serv ...
- k8s+Jenkins+GitLab-自动化部署项目
0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 k8s架构目录:Kubernetes(k8s)集群部署(k8s企业级Docker容器集群管理)系列目录 此文阅读目录: 1.闲聊 ...
- 前端与算法 leetcode 242. 有效的字母异位词
目录 # 前端与算法 leetcode 242. 有效的字母异位词 题目描述 概要 提示 解析 解法一:哈希表 解法二:数组判断字符出现次数 解法三:转换字符串 算法 传入测试用例的运行结果 执行结果 ...
- Apache Kafka - How to Load Test with JMeter
In this article, we are going to look at how to load test Apache Kafka, a distributed streaming plat ...
- 一个萝卜一个坑#我的C坑_两局变量
前面的笔记慢慢补 全局变量和局部变量的区别: 1.首字母 尽量不用全局变量原因: 1.占内存 2.降低通用性和可靠性 3.降清晰度 若在同一源文件中,全局变量和局部变量同名,记住很重要的一条:实参决定 ...
- Gearman介绍、原理分析、实践改进
gearman是什么? 它是分布式的程序调用框架,可完成跨语言的相互调用,适合在后台运行工作任务.最初是2005年perl版本,2008年发布C/C++版本.目前大部分源码都是(Gearmand服务j ...