netty的使用
来源:互联网 发布:怎么卸载java 编辑:程序博客网 时间:2024/05/18 01:33
官网
http://netty.io/
近来有一个项目说是想要用netty来做代理,之前没搞过,网上百度了下,这是nio框架,nio 之前在 node 的时候接触过,是对io密集型的系统 有效的 思路.
这里对netty进行简单的入门
怎么使用netty?
使用非常简单,如果使用过jetty(貌似就名字像,和netty没啥关系),就知道,引入jar包,直接一个main嵌入server代码即可.
我是用maven来构建,直接在pom.xml中copy下面的依赖,即可使用
<!-- https://mvnrepository.com/artifact/io.netty/netty-all --><dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.0.44.Final</version></dependency>
官网简单例子
这里介绍官网的helloworld例子,一个客户端,一个服务端,
客户端不用代码了,直接用telnet ,使用如telnet 127.0.0.1 端口, 调用服务端情况.
服务端有两个java.一个main和初始代的类,另一个是handler 类
- DiscardServer.java
channelRead方法 是具体的处理逻辑,每次请求都通过这个方法
import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.util.ReferenceCountUtil;/** * Handles a server-side channel. */public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1)tel @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf in = (ByteBuf) msg; try { System.out.println(msg); //每次请求会打印 ctx.write(msg); // (1) //每次请求会返回 ctx.flush(); // (2) } catch(Exception e ) { ReferenceCountUtil.release(msg); // (2) } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4) // Close the connection when an exception is raised. cause.printStackTrace(); ctx.close(); }}
- DiscardServerHandler
这是服务启动类(main),加上netty配置
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;public class DiscardServer { private int port; public DiscardServer(int port) { this.port = port; } public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1) EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); // (2) b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) // (3) .childHandler(new ChannelInitializer<SocketChannel>() { // (4) @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new DiscardServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) // (5) .childOption(ChannelOption.SO_KEEPALIVE, true); // (6) // Bind and start to accept incoming connections. ChannelFuture f = b.bind(port).sync(); // (7) // Wait until the server socket is closed. // In this example, this does not happen, but you can do that to gracefully // shut down your server. 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(); }}
结果,结果很简单,我输入123,显示如下
- 说明
112233是telnet客户端上,因为有ctx.write(msg); 这一行,所以123变成了112233
Time server
官网中有个时间服务器, 实现的协议是 TIME协议1
我并不了解time server有什么作用,不过功能上来讲,就是客户端请求,服务端把自己的时间扔回给客户端,并且扔回的时间形式有要求,32位的int
根据time protocol 要实现这样的流程
S检测端口37
U 连接到端口37
S 以32位二进制数发送时间
U 接收时间
U 关闭连接
S 关闭连接
说明:在连接被创建发送一个消息,所以这次我们不能使用 channelRead() 方法了,代替他的是,我们需要覆盖 channelActive() 方法
这里一个服务端,一个客户端,各两个类
- TimeServer服务启动类
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;public class TimeServer { private int port; public TimeServer(int port) { this.port = port; } public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1) EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); // (2) b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) // (3) .childHandler(new ChannelInitializer<SocketChannel>() { // (4) @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new TimeServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) // (5) .childOption(ChannelOption.SO_KEEPALIVE, true); // (6) // Bind and start to accept incoming connections. ChannelFuture f = b.bind(port).sync(); // (7) // Wait until the server socket is closed. // In this example, this does not happen, but you can do that to gracefully // shut down your server. 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 TimeServer(port).run(); }}
- TimeServerHandler
服务处理类
import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelFutureListener;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;/** * Handles a server-side channel. */public class TimeServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(final ChannelHandlerContext ctx) { // (1) final ByteBuf time = ctx.alloc().buffer(4); // (2) time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L)); //写成这样貌似是 协议的一部分 final ChannelFuture f = ctx.writeAndFlush(time); // (3) f.addListener(ChannelFutureListener.CLOSE); // 写完后就close了 } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); }}
- TimeClient.java
时间客户端启动类
import io.netty.bootstrap.Bootstrap;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.NioSocketChannel;public class TimeClient { public static void main(String[] args) throws Exception { String host = "127.0.0.1"; int port = Integer.parseInt("8080"); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); // (1) b.group(workerGroup); // (2) b.channel(NioSocketChannel.class); // (3) b.option(ChannelOption.SO_KEEPALIVE, true); // (4) b.handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new TimeClientHandler()); } }); // Start the client. ChannelFuture f = b.connect(host, port).sync(); // (5) // Wait until the connection is closed. f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); } }}
- TimeClientHandler
时间处理类,这里接收到信息后打印
import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import java.util.Date;public class TimeClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf m = (ByteBuf) msg; // (1) try { long result = m.readUnsignedInt(); System.out.println("from server:"+result); long currentTimeMillis = (result - 2208988800L) * 1000L; System.out.println("serverTime:"+new Date(currentTimeMillis)); ctx.close(); } finally { m.release(); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); }}
先把服务端启动,然后调客户端的main
客户端打印以下信息:
from server:3696844797serverTime:Thu Feb 23 21:19:57 CST 2017
- Time Protocol,计算机协议术语,此协议提供了一个独立于站点的,机器可读的日期和时间信息。http://www.baike.com/wiki/Time+Protocol ↩
0 0
- Netty的使用模式
- netty的使用记录
- netty的使用
- netty的使用
- Netty的LengthFieldBasedFrameDecoder使用
- Netty 之 Netty使用Google的ProtoBuf
- netty的个人使用心得
- netty中LengthFieldBasedFrameDecoder的使用
- netty中LengthFieldBasedFrameDecoder的使用
- netty中LengthFieldBasedFrameDecoder的使用
- Netty开源库的初步使用
- netty中LengthFieldBasedFrameDecoder的使用
- Netty框架的基本使用
- netty的简单使用实例
- Jboss .netty项目使用的netty包详解之 org.jboss.netty.handler.codec.base64
- Netty的分隔符解码器的使用
- 使用Netty代理你的请求
- java netty decoder与encoder的使用
- 根据二叉树的前序遍历和中序遍历的结果,重建二叉树
- HIve On Spark 安装, Mysql配置,执行引擎设置
- C++学习---(三)面向对象的优缺点
- C语言中如何将二维数组作为函数的参数传递
- mysql的优化(表的设计,优化步骤,四种索引,分析慢查询,使用索引的深入解析,存储引擎分析,表的分割,数据库配置)
- netty的使用
- 黑客数字雨
- win32+VS2013下使用pthread
- 实用英语
- SQLite指令
- XML笔记
- LeetCode Problem 237. Delete Node in a Linked List
- Unity 3D 文件加密下 AES的加密解密使用
- linux下Jenkins自动构建android