netty的简单实现
来源:互联网 发布:加入网络作协要求 编辑:程序博客网 时间:2024/05/20 14:16
概述
本篇博客通过简单的demo实现netty的使用
netty3
1、添加netty3的maven依赖
<dependency> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> <version>3.2.10.Final</version> </dependency>
2、服务端的demo
package five.heart3;import org.jboss.netty.bootstrap.ServerBootstrap;import org.jboss.netty.channel.ChannelPipeline;import org.jboss.netty.channel.ChannelPipelineFactory;import org.jboss.netty.channel.Channels;import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;import org.jboss.netty.handler.codec.string.StringDecoder;import org.jboss.netty.handler.codec.string.StringEncoder;import org.jboss.netty.handler.timeout.IdleStateHandler;import org.jboss.netty.util.HashedWheelTimer;import java.net.InetSocketAddress;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * Created with IntelliJ IDEA. * User: ipaynow * Date: 17-6-24 * Time: 下午5:56 * netty服务端 */public class Server { public static void main(String[] args){ //服务类 ServerBootstrap serverBootstrap = new ServerBootstrap(); //boss线程监听端口,worker线程负责数据读写 ExecutorService boss = Executors.newCachedThreadPool(); ExecutorService worker = Executors.newCachedThreadPool(); //设置NioSocket工厂 serverBootstrap.setFactory(new NioServerSocketChannelFactory(boss,worker)); final HashedWheelTimer hashedWheelTimer = new HashedWheelTimer(); //定时器 //设置管道的工厂 serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline channelPipeline = Channels.pipeline(); //定时器,读超时,写超时,读写超时 channelPipeline.addLast("idle",new IdleStateHandler(hashedWheelTimer,5,5,10)); channelPipeline.addLast("decoder",new StringDecoder()); channelPipeline.addLast("encoder",new StringEncoder()); channelPipeline.addLast("helloHandler",new HelloHandler()); return channelPipeline; } }); //netty3中对应设置如下 serverBootstrap.setOption("backlog",1024); //ServerSocketChannel的设置,链接缓冲池的大小 serverBootstrap.setOption("keepAlive",true);//socketChannel的设置,维持链接的活跃,清楚死链接 serverBootstrap.setOption("tcpNoDelay",true); //socketChannel的设置,关闭延迟发送 serverBootstrap.bind(new InetSocketAddress(10101)); System.out.println("start!!!"); }}
package five.heart3;import org.jboss.netty.channel.*;import org.jboss.netty.handler.timeout.IdleState;import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;import org.jboss.netty.handler.timeout.IdleStateEvent;/** * Created with IntelliJ IDEA. * User: ipaynow * Date: 17-6-24 * Time: 下午6:17 * To change this template use File | Settings | File Templates. *///public class HelloHandler extends SimpleChannelHandler {public class HelloHandler extends IdleStateAwareChannelHandler implements ChannelHandler { @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { System.out.println(e.getMessage()); } @Override public void handleUpstream(final ChannelHandlerContext ctx, ChannelEvent e) throws Exception { if(e instanceof IdleStateEvent){ if(((IdleStateEvent)e).getState() == IdleState.ALL_IDLE){ System.out.println("提玩家下线"); ChannelFuture channelFuture = ctx.getChannel().write("time out,you will close"); channelFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { ctx.getChannel().close(); } }); } }else{ super.handleUpstream(ctx,e); } }}
netty5
1、添加netty5的maven依赖
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>5.0.0.Alpha2</version> </dependency>
2、服务端的demo
package five.heart5;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.*;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.handler.timeout.IdleStateHandler;/** * Created with IntelliJ IDEA. * User: ipaynow * Date: 17-6-24 * Time: 下午7:18 * To change this template use File | Settings | File Templates. */public class Server { public static void main(String[] args){ //服务类 ServerBootstrap serverBootstrap = new ServerBootstrap(); //boss和worker EventLoopGroup boss = new NioEventLoopGroup(); EventLoopGroup worker = new NioEventLoopGroup(); try{ //设置线程池 serverBootstrap.group(boss,worker); //设置NioSocket工厂 serverBootstrap.channel(NioServerSocketChannel.class); //设置管道工厂 serverBootstrap.childHandler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel channel) throws Exception { channel.pipeline().addLast(new IdleStateHandler(5,5,10)); channel.pipeline().addLast(new StringDecoder()); channel.pipeline().addLast(new StringEncoder()); channel.pipeline().addLast(null); } }); //设置参数,TCP参数 serverBootstrap.option(ChannelOption.SO_BACKLOG,2048);//ServerSocketChannel的设置,链接缓冲池的大小 serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE,true);//socketChannel的设置,维持链接的活跃,清楚死链接 serverBootstrap.childOption(ChannelOption.TCP_NODELAY,true);//socketChannel的设置,关闭延迟发送 //绑定端口 ChannelFuture channelFuture = serverBootstrap.bind(10101); System.out.println("start"); //等待服务端关闭 channelFuture.channel().closeFuture().sync(); }catch (Exception ex){ ex.printStackTrace(); }finally { //释放资源 boss.shutdownGracefully(); worker.shutdownGracefully(); } }}
package five.heart5;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.timeout.IdleStateEvent;/** * Created with IntelliJ IDEA. * User: ipaynow * Date: 17-6-24 * Time: 下午7:29 * To change this template use File | Settings | File Templates. */public class ServerHandler extends SimpleChannelInboundHandler<String> { @Override protected void messageReceived(ChannelHandlerContext channelHandlerContext, String msg) throws Exception { System.out.println(msg); channelHandlerContext.channel().writeAndFlush("hi"); channelHandlerContext.writeAndFlush("hi"); } @Override public void userEventTriggered(final ChannelHandlerContext channelHandlerContext,Object evt) throws Exception{ if(evt instanceof IdleStateEvent){ } }}
客户端
1、可以使用telnet进行测试上面的服务器端
2、可以编程netty的单client端
package four.client;import io.netty.bootstrap.Bootstrap;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioSocketChannel;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import java.io.BufferedReader;import java.io.InputStreamReader;/** * Created with IntelliJ IDEA. * User: ipaynow * Date: 17-6-24 * Time: 下午4:01 * To change this template use File | Settings | File Templates. */public class Client { public static void main(String[] args){ //服务类 Bootstrap bootstrap = new Bootstrap(); //worker EventLoopGroup worker = new NioEventLoopGroup(); try{ //设置线程池 bootstrap.group(worker); //设置socket工厂 bootstrap.channel(NioSocketChannel.class); //设置管道 bootstrap.handler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel channel) throws Exception { channel.pipeline().addLast(new StringDecoder()); channel.pipeline().addLast(new StringEncoder()); channel.pipeline().addLast(new ClientHandler()); } }); ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 10101); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); while (true){ System.out.println("请输入:"); String msg = bufferedReader.readLine(); channelFuture.channel().writeAndFlush(msg); } }catch (Exception ex){ ex.printStackTrace(); }finally { worker.shutdownGracefully(); } }}
package four.client;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;/** * Created with IntelliJ IDEA. * User: ipaynow * Date: 17-6-24 * Time: 下午4:08 * To change this template use File | Settings | File Templates. */public class ClientHandler extends SimpleChannelInboundHandler<String> { @Override protected void messageReceived(ChannelHandlerContext channelHandlerContext, String msg) throws Exception { System.out.println("客户端收到消息:"+msg); }}
3、可以编程netty的多client端
package four.client;import io.netty.bootstrap.Bootstrap;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioSocketChannel;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import java.util.ArrayList;import java.util.List;import java.util.concurrent.atomic.AtomicInteger;/** * Created with IntelliJ IDEA. * User: ipaynow * Date: 17-6-24 * Time: 下午4:18 * 多连接客户端 */public class MultClient { //服务类 private Bootstrap bootstrap = new Bootstrap(); //会话:Channel对象是线程安全的对象 private List<Channel> channels = new ArrayList<>(); //引用计数 private final AtomicInteger atomicInteger = new AtomicInteger(); //引用计数 public void init(int count){ //worker EventLoopGroup worker = new NioEventLoopGroup(); //设置线程池 bootstrap.group(worker); //设置socket工厂 bootstrap.channel(NioSocketChannel.class); //设置管道 bootstrap.handler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel channel) throws Exception { channel.pipeline().addLast(new StringDecoder()); channel.pipeline().addLast(new StringEncoder()); channel.pipeline().addLast(new ClientHandler()); } }); for(int i=1;i<=count;i++){ ChannelFuture channelFuture = bootstrap.connect("127.0.0.1",10101); channels.add(channelFuture.channel()); } } //获取会话 public Channel nextChannel(){ return getFirstActiveChannel(0); } private Channel getFirstActiveChannel(int count){ Channel channel = channels.get(Math.abs(atomicInteger.getAndIncrement() % channels.size())); if(!channel.isActive()){ //重连 reconnect(channel); if(count>=channels.size()){ throw new RuntimeException("no can use channel"); } return getFirstActiveChannel(count + 1); } return channel; } //重连 private void reconnect(Channel channel){ synchronized (channel){ if(channels.indexOf(channel) == -1){ return; } Channel newChannel = bootstrap.connect("127.0.0.1",10101).channel(); channels.set(channels.indexOf(channel),newChannel); } }}
package four.client;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;/** * Created with IntelliJ IDEA. * User: ipaynow * Date: 17-6-24 * Time: 下午4:56 * To change this template use File | Settings | File Templates. */public class Start { public static void main(String[] args) { MultClient client = new MultClient(); client.init(5); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); while (true){ try { System.out.println("请输入:"); String msg = bufferedReader.readLine(); client.nextChannel().writeAndFlush(msg); } catch (IOException e) { e.printStackTrace(); } } }}
总结
关于netty的使用基本上就是上面的内容,在netty的多链接客户端中Channel是线程安全的(新线程时,会写时会将该内容分装成一个任务,给一个单线程池),所以我们当我们多个线程操作同一个Channel对象的时候,是不会出现线程安全的问题,所以,在netty的多链接客户端中采用的是对象组而不是对象池。
阅读全文
0 0
- netty的简单实现
- 用Netty实现的简单HTTP服务器
- 用Netty实现的简单HTTP服务器
- 用Netty实现的简单HTTP服务器
- Netty框架实现简单的组播
- netty 简单httpserver实现
- Netty实现简单聊天室
- netty实现简单聊天室
- Netty实现简单RPC
- 基于Netty的RPC简单框架实现(四):Netty实现网络传输
- 简单的netty demo
- netty的简单介绍
- netty框架的udp方式的简单实现
- Netty实现简单网络通信
- Netty实现简单HTTP服务器
- Netty 实现简单RPC调用
- netty学习之路(一) netty+protocolbuffer 实现简单的消息发送
- Netty实例-简单的服务端-客户端实现,注释详细
- MySQL 基础 —— 字符串处理
- 9.1常用类(String类)
- 【hdu 1286】找新朋友(欧拉函数)
- 例说数据结构&STL(十)——hash_set/unordered_set
- 数据结构--链表
- netty的简单实现
- System.Environment类
- 哲学家就餐问题
- linux下git环境变量配置
- 单词翻转
- java对象和Map互转及测试
- Codeforces contest 787 recordings
- C++详解Leetcode:106. Construct Binary Tree from Inorder and Postorder Traversal
- 精度丢失