Netty学习

来源:互联网 发布:如何克隆淘宝店铺 编辑:程序博客网 时间:2024/05/21 07:27

使用netty实现一个tcp的echo服务器。

(1)导入netty 的jar

(2)在主文件中搭建框架

package com.xing.echoserver;import java.net.InetSocketAddress;import java.util.concurrent.Executors;import org.jboss.netty.bootstrap.ServerBootstrap;import org.jboss.netty.channel.ChannelFactory;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;public class DiscardServer {    public static void main(String[] args) throws Exception {        ChannelFactory factory =            new NioServerSocketChannelFactory(                    Executors.newCachedThreadPool(),                    Executors.newCachedThreadPool());        ServerBootstrap bootstrap = new ServerBootstrap(factory);        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {            public ChannelPipeline getPipeline() {                return Channels.pipeline(new DiscardServerHandler());//这里的DiscardServerHandler实现我们的逻辑,需要            }        });        bootstrap.setOption("child.tcpNoDelay", true);//设置连接的一些属性        bootstrap.setOption("child.keepAlive", true);        bootstrap.bind(new InetSocketAddress(1872));//设置本地端口    }}

对于上面的代码大部分是框架性质的我们先不去深究,把有注释的几个地方搞清楚就够。

(3)在类中实现我们的业务逻辑。

package com.xing.echoserver;import org.jboss.netty.channel.Channel;import org.jboss.netty.channel.ChannelHandlerContext;import org.jboss.netty.channel.ExceptionEvent;import org.jboss.netty.channel.MessageEvent;import org.jboss.netty.channel.SimpleChannelHandler;public class DiscardServerHandler extends SimpleChannelHandler {    @Override    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {//收到消息是怎么办    Channel ch = e.getChannel();//拿到连接        ch.write(e.getMessage());//将收到的消息写回连接    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {        e.getCause().printStackTrace();                Channel ch = e.getChannel();        ch.close();    }}

(4)下面我们实现另外一个服务器-Time服务端程序,他的功能要求在客户端连接过来后,server马上发送一个当前的时间值(int类型的数据),而且发送成功之后马上关闭连接。

这里我们要重写的方法就不是messageReceived了,而是chennelConnected.

package org.jboss.netty.example.time;public class TimeServerHandler extends SimpleChannelHandler {    @Override    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {        Channel ch = e.getChannel();//注意这里的Channel我们要引用netty包下面的Channel,而不是NIO包里面的Channel,因为netty对NIO的实现进行了增强。                ChannelBuffer time = ChannelBuffers.buffer(4);//ChannelBuffers是一个帮助类,为我们实现分配buffer的功能,我们要发送一个int所以申请buffer 的长度是4        time.writeInt((int) (System.currentTimeMillis() / 1000));                ChannelFuture f = ch.write(time);//这里我们不需要flip,因为这里是netty的世界,不是NIO的世界,在这里ChannelBuffer有read、write两个指针分别用于读、写,方便多了。而且这里我们返回一个ChannelFuture,我们这么做是为了实现异步调用。我们不能马上调用ch.close                f.addListener(new ChannelFutureListener() {//这里是一个匿名内部类,在完成write操作之后,Netty框架会执行operationComplete方法里面的代码            public void operationComplete(ChannelFuture future) {                Channel ch = future.getChannel();                ch.close();            }        });    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {        e.getCause().printStackTrace();        e.getChannel().close();    }}

(5)Netty实现time 协议的客户端




原创粉丝点击