?
不喜欢写描述什么的,基本上使用步骤,注意事项都在代码注释中标明了,而相关的内容网上有很多,比自己的理解更好,所以自己对某个知识点的理解则都写在了为知笔记中。
1、服务端的编写
package com.netty.helloserver; import java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; /** * @author Chalmers 2016年2月18日 下午6:49:57 */ public class NettyServer { public static void main(String[] args) { // 创建服务类对象 ServerBootstrap serverBootstrap = new ServerBootstrap(); // 创建两个线程池 // 简单来讲,就是boss监听端口,worker来监听selector(NIO里面的) ExecutorService boss = Executors.newCachedThreadPool(); ExecutorService worker = Executors.newCachedThreadPool(); // 设置工厂,并且把两个线程池加入进去 // 经测试,该方法在netyy3.0中有效,5.0中没有 serverBootstrap.setFactory(new NioServerSocketChannelFactory(boss, worker)); // 设置管道工厂 serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline channelPipeline = Channels.pipeline(); // 加上此行代码,在Handler中便可以直接获取字符串,而不用经过ChannelBuffer了 // 看源码可得,decoder用来处理上行数据 channelPipeline.addLast("decoder", new StringDecoder()); // encoder用来数据下行数据 channelPipeline.addLast("encoder", new StringEncoder()); /** * 经测试可得,decoder和encoder不能省去,而下面的可以省掉 */ channelPipeline.addLast("helloHandler", new ServerHandler()); // 返回 return channelPipeline; } }); // 注意此行代码,在绑定时,一定要在工厂之后,否则就会报错 serverBootstrap.bind(new InetSocketAddress(9090)); System.out.println("start --> server"); } } class ServerHandler extends SimpleChannelHandler { /** * 不管是否已经连接,都将执行 */ @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelClosed(ctx, e); System.out.println("channelClosed"); } /** * 当网络连接时执行 */ @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelConnected(ctx, e); System.out.println("channelConnected"); } /** * 只有当网络连接过,断开时才会执行 */ @Override public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelDisconnected(ctx, e); System.out.println("channelDisconnected"); } /** * 捕获异常 */ @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { super.exceptionCaught(ctx, e); System.out.println("exceptionCaught"); } /** * 接收消息 */ @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { super.messageReceived(ctx, e); System.out.println("messageReceived"); // 因为在设置管道工厂时,设置了StringDecode,所以在此时可以直接获得 // 但如果没有设置的话,可以通过以下方法 // ChannelBuffer message = (ChannelBuffer) e.getMessage(); // System.out.println(new String(message.array())); System.out.println(e.getMessage()); /* * 发送消息 */ // ChannelBuffer copiedBuffer = ChannelBuffers.copiedBuffer("hi" // .getBytes()); // ctx.getChannel().write(copiedBuffer); // 因为在管道中设置了encoder,所以可以像读取一样,写成下面的形式 ctx.getChannel().write("hi"); } }
?
?
2、客户端的编写
package com.netty.hiclient; import java.net.InetSocketAddress; import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory; import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; /** * @author Chalmers 2016年2月18日 下午10:22:08 */ public class NettyClient { private static ClientBootstrap clientBootstrap; public static void main(String[] args) { // 获得客户端对象 clientBootstrap = new ClientBootstrap(); // 创建两个线程池 ExecutorService boss = Executors.newCachedThreadPool(); ExecutorService worker = Executors.newCachedThreadPool(); // 设置工厂,跟服务端一样 clientBootstrap.setFactory(new NioClientSocketChannelFactory(boss, worker)); // 设置管道工厂 clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline channelPipeline = Channels.pipeline(); // 进行包装 channelPipeline.addLast("decoder", new StringDecoder()); channelPipeline.addLast("encoder", new StringEncoder()); channelPipeline.addLast("hiHandler", new ClientHandler()); return channelPipeline; } }); System.out.println("start --> client"); // 一定记住,这个地方用的是connect,而不是bind ChannelFuture channelFuture = clientBootstrap .connect(new InetSocketAddress("127.0.0.1", 9090)); // 可以冲future中获得channel Channel channel = channelFuture.getChannel(); Scanner sc = new Scanner(System.in); while (true) { System.out.print("输入: "); // 用获得channel进行输出 channel.write(sc.next()); } } } class ClientHandler extends SimpleChannelHandler { @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelClosed(ctx, e); System.out.println("channelClosed"); } @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelConnected(ctx, e); System.out.println("channelConnected"); } @Override public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { super.channelDisconnected(ctx, e); System.out.println("channelDisconnected"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { super.exceptionCaught(ctx, e); System.out.println("exceptionCaught"); } @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { super.messageReceived(ctx, e); System.out.println("messageReceived"); System.out.println(e.getMessage()); } }
?
原文:http://moonmonster.iteye.com/blog/2278672