使用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(); } }
这里我们要重写的方法就不是messageReceived了,而是chennelConnected.
package org.jboss.netty.example.time; public class TimeServerHandler extendsSimpleChannelHandler
{ @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(newChannelFutureListener
() {//这里是一个匿名内部类,在完成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 协议的客户端