【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 ...
随机推荐
- BootstrapTable的简单使用教程
1.引入必须的几个包 <link th:href="bootstrap/css/bootstrap.css}"/> <link th:href="boo ...
- 《Machine Learning - 李宏毅》视频笔记(完结)
https://www.youtube.com/watch?v=CXgbekl66jc&list=PLJV_el3uVTsPy9oCRY30oBPNLCo89yu49 https://www. ...
- Js中的排他思想
<body> <button>按钮1</button> <button>按钮2</button> <butto ...
- virtualbox安装问题总结
还是老问题 重点重点: https://blog.csdn.net/Loisleen/article/details/84975165#1install_the_gcc_make_perl_packa ...
- 动态的src路径怎么写
错误写法 <div class="icon--wrapper" @click="before"> <img class="icon- ...
- vue自学小demo----前端
vue学习的小demo,实现简单的页面项目的增删 代码如下 <!DOCTYPE html> <html> <head> <meta charset=" ...
- React创建组件的方法,组件的props属性、state属性的用法和特点,父子组件传值,兄弟组件传值
创建组件的方法,组件的props属性.state属性的用法和特点,父子组件传值,兄弟组件传值 1.react组件 1.1.创建组件的方法 1.1.1.函数组件 定义一个组件最简单的方式是使用JavaS ...
- RPA系列之(二)-UIPath学习目录
如何一步步渐入佳境,跟着目录一点一点来 UiPath简介 UiPath下载安装与激活 UiPath第一个案例Hello World UiPath变量的介绍和使用-1 UiPath变量的介绍和使用-2 ...
- express框架,使用 static 访问 public 内静态文件
使用 express 生成 node 服务器后,我们需要访问放在public文件夹内的静态文件,如上传的图片 我们需要在app.js中添加配置项: app.use('/public',express. ...
- Azure DevOps Server 2019 第一个补丁包(2019.0.1 RTW)
在Azure DevOps Server 2019正式发布后的2周左右时间,微软快速发布了第一个补丁包Azure DevOps Server 2019.0.1 RTW.Azure DevOps Ser ...