Netty系列入门之HelloWorld(一)

一. 简介

Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.

'Quick and easy' doesn't mean that a resulting application will suffer from a maintainability or a performance issue. Netty has been designed carefully with the experiences earned from the implementation of a lot of protocols such as FTP, SMTP, HTTP, and various binary and text-based legacy protocols. As a result, Netty has succeeded to find a way to achieve ease of development, performance, stability, and flexibility without a compromise.

  上面一段话引子Netty官网:Netty是一个基于NIO的客户端与服务端框架,可以让我们简单快速的开发协议化的客户端/服务端的网络应用。Netty可以非常简单的进行网络编程,例如TCP和UDP的套接字服务。"快速和简单"并不意味着我们使用Netty编写的应用很难维护,也不会导致性能问题。Netty的设计非常的谨慎,设计Netty的经验来源于对FTP, SMTP,HTTP以及遗留的各种二进制和基于文本的协议的大量的实现。总之,Netty在实现了快速快发,高性能,稳定性强,易于扩展方面寻找到一种极佳的方式,而不会为了某些因素作出任何的妥协。

  当然,以上只是官网的陈述,笔者发现几乎所有的框架都会使用"简单"、"易于使用"这类的词语,然而笔者在学习Netty的过程中并不这么认为,可能是笔者智商有限吧。那么多的不说了,按照笔者一贯的风格,我们就直接上代码吧。

二. Netty入门之HelloWorld

  对于Netty来说,编写一个"Hello World"程序并不是那么的简单,对于初学Netty的人来讲,可能觉得异常的繁琐,怎么说了,繁琐也得学呀,谁让咱走上了编程这条不归路呢?

2.1 Netty的启动服务程序

public class ServerTest {
public static void main(String[] args) throws InterruptedException {
/**
* bossGroup, 父类的事件循环组只是负责连接,获取到连接后交给 workergroup子的事件循环组,
* 参数的获取,业务的处理等工作均是由workergroup这个子事件循环组来完成,一个事件循环组一样
* 可以完成所有的工作,但是Netty推荐的方式是使用两个事件循环组。
*/
EventLoopGroup bossGroup = new NioEventLoopGroup(); //创建父事件循环组
EventLoopGroup workerGroup = new NioEventLoopGroup(); //创建子类的事件循环组 try{
//创建启动服务器的对象
ServerBootstrap serverBootstrap = new ServerBootstrap(); /**
* group方法接收两个参数, 第一个为父时间循环组,第二个参数为子事件循环组
*/
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) //bossGroup的通道,只是负责连接
.childHandler(new TestChannelnitializer()); //workerGroup的处理器, ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); //绑定端口
channelFuture.channel().closeFuture().sync(); }finally{
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}

2.2 通道初始化程序

  通道的初始化程序主要是为workerGroup添加各种Handler.

/**
* 初始化一个通道,主要用于设置各种Handler
*/
public class TestChannelnitializer extends ChannelInitializer<SocketChannel>{ @Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
/**
* Handler就相当于Servlet中的过滤器, 请求和响应都会走Handler
* HttpServerCodec: http的编解码器,用于Http请求和相应
*/
pipeline.addLast("httpServerCodec", new HttpServerCodec());
pipeline.addLast("testHttpServerHandler", new TestHttpServerHandler());
}
}

2.3 自定义的Handler

/**
* 自定义处理器
*/
public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject>{ @Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if(msg instanceof HttpRequest){
//要返回的内容, Channel可以理解为连接,而连接中传输的信息要为ByteBuf
ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8); //构造响应
FullHttpResponse response =
new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content); //设置头信息的的MIME类型
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); //内容类型
//设置要返回的内容长度
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes()); //内容长度
//将响应对象返回
ctx.writeAndFlush(response);
}
} //通道注册成功
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel register...");
super.channelRegistered(ctx);
} /**
* 自定义的Handler被添加,也就是在TestChannelnitializer的initChannel方法中,
* pipeline.addLast("testHttpServerHandler", new TestHttpServerHandler());
* 这行代码执行的时候,该方法被触发
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
System.out.println("handler added...");
super.handlerAdded(ctx);
} //通道处于活动状态,即可用状态
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel active...");
super.channelActive(ctx);
} //通道处于不活动状态
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel inactive...");
super.channelInactive(ctx);
} //通道取消注册
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel unregister...");
super.channelUnregistered(ctx);
}
}

三.运行

  首先启动ServerTest的主函数,然后再网页中输入: http://localhost:88899,就会出现你希望看到的东西(前提是代码要写对),如下图:

四.总结

  很多人可能看到该代码会觉得头昏脑胀,谁不是呢?笔者对于编程的学习方式一直都是:不懂就敲,先学会用,还是不懂,接着敲,直到敲到你认为很多东西理所当然了,就是会了。

Netty入门之HelloWorld的更多相关文章

  1. Netty学习_Netty框架入门教程:Netty入门之HelloWorld实现

    我们可能都学过Socket通信/io/nio/aio等的编程.如果想把Socket真正的用于实际工作中去,那么还需要不断的完善.扩展和优化.比如很经典的Tcp读包写包问题,或者是数据接收的大小,实际的 ...

  2. Netty 系列(三)Netty 入门

    Netty 系列(三)Netty 入门 Netty 是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序.更多请参考:Netty Github 和 Netty中文 ...

  3. Netty入门之客户端与服务端通信(二)

    Netty入门之客户端与服务端通信(二) 一.简介 在上一篇博文中笔者写了关于Netty入门级的Hello World程序.书接上回,本博文是关于客户端与服务端的通信,感觉也没什么好说的了,直接上代码 ...

  4. Netty入门

    一.NIO Netty框架底层是对NIO的高度封装,所以想要更好的学习Netty之前,应先了解下什么是NIO - NIO是non-blocking的简称,在jdk1.4 里提供的新api,他的他的特性 ...

  5. netty入门(一)

    1. netty入门(一) 1.1. 传统socket编程 在任何时候都可能有大量的线程处于休眠状态,只是等待输入或者输出数据就绪,这可能算是一种资源浪费. 需要为每个线程的调用栈都分配内存,其默认值 ...

  6. Netty入门(三)之web服务器

    Netty入门(三)之web服务器 阅读前请参考 Netty入门(一)之webSocket聊天室 Netty入门(二)之PC聊天室 有了前两篇的使用基础,学习本文也很简单!只需要在前两文的基础上稍微改 ...

  7. Netty入门(二)之PC聊天室

    参看Netty入门(一):Netty入门(一)之webSocket聊天室 Netty4.X下载地址:http://netty.io/downloads.html 一:服务端 1.SimpleChatS ...

  8. Netty入门(一)之webSocket聊天室

    一:简介 Netty 是一个提供 asynchronous event-driven (异步事件驱动)的网络应用框架,是一个用以快速开发高性能.高可靠性协议的服务器和客户端. 换句话说,Netty 是 ...

  9. netty同时做http和websocket(netty入门)

    ---恢复内容开始--- http://www.jianshu.com/p/5c29c6c6d28c ---恢复内容结束--- http://www.jianshu.com/p/5c29c6c6d28 ...

随机推荐

  1. Foxmail 7.0破解版,拷贝到新机器后,发送邮件乱码问题

    申请了新机器,挺开心,键盘和鼠标也好用了,但是新机器也随之而来一些不便,以前存储的数据需要重新拷贝.还有一些邮件,有些邮件标记了*号. Foxmail7.0绿色版本还挺好用,直接拷贝到新机器上就能直接 ...

  2. Android实战简易教程-第三十四枪(基于ViewPager和FragmentPagerAdapter实现滑动通用Tab)

    上一段时间写过一篇文章<基于ViewPager实现微信页面切换效果> 里面实现了相似微信Tab的页面.可是这样的实现方法有个问题.就是以后全部的代码逻辑都必须在MainActivity中实 ...

  3. 模拟教室网络(跨VLAN,跨网段通讯)

    要求: 1,跨VLAN,三个教室在不同的VLAN中,翻番至网络风暴 2,三个VLAN在三个不同的网段 3,设置访问控制列表,组织每个网段的前八个IP不可访问服务器 4,其他IP均可访问外网的服务器 操 ...

  4. HTTPS加密流程超详解(一)前期准备

    0.前言 前一阵子想写一个HTTPS的嗅探工具,之前只是大致了解SSL/TLS协议的加密流程,真正上起手来一步一步分析发现还是有点复杂的,于是我参考了wireshark的源码以及各种RFC,弄清楚了S ...

  5. Grafana4.2安装

    一.文件准备 1.1 文件名称 grafana-4.2.0-1.x86_64.rpm 1.2 下载地址 https://grafana.com/grafana/download 二.工具准备 2.1 ...

  6. 【java】抓取页面内容,提取链接(此方法可以http get无需账号密码的请求)

    package 网络编程; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileOutpu ...

  7. 【java】缓冲字符字节输入输出流:java.io.BufferedReader、java.io.BufferedWriter、java.io.BufferedInputStream、java.io.BufferedOutputStream

    BufferedReader最重要,因为有个方法public String readLine() package System输入输出; import java.io.BufferedReader; ...

  8. XE10 clientDataset 访问 DataSnap 服务端报错问题,锲而不舍找方法,终于解决了

    1. 开发环境说明:win 10 下安装了XE10.2和Delphi7 2.按照网上datasnap 三层与使用xe10 自带的samples 的例子,访问数据库都要报莫名的地址错误,这个太不人性化: ...

  9. [array] leetcode - 53. Maximum Subarray - Easy

    leetcode - 53. Maximum Subarray - Easy descrition Find the contiguous subarray within an array (cont ...

  10. [array] leetcode - 48. Rotate Image - Medium

    leetcode - 48. Rotate Image - Medium descrition You are given an n x n 2D matrix representing an ima ...