知識點
1、消息如何在管道中流轉 ,一個管道中會有多個handler,當前的一個handler如何往下面的一個handler傳遞一個對象 主要通過handler往下傳遞對象的方法是sendUpstream(event) 2、看下粘包和分包是怎么樣一個情況 hello hello 通過定義一個穩定的結構 length + hello 1、為什么FrameDecoder return的對象就是往下傳遞的對象 (還是調用了sendUpstream) 2、buffer里面數據未被讀取完怎么辦? (cumulation緩存) 3、為什么return null就可以緩存buffer (cumulation緩存) =============================分割線=========================== 3、FrameDecoder里面的cumulation其實就是一個緩存的buffer對象 包頭+長度+數據 把長度定義的很大,這種數據包,通常被稱為socket攻擊,字節流式攻擊
1、Client.java
package com.example.netty.lesson11.pipeLine; import java.net.Socket; public class Client { public static void main(String[] args) throws Exception { Socket socket = new Socket("127.0.0.1", 51503); socket.getOutputStream().write("hello".getBytes()); socket.close(); } }
2、Server.java
package com.example.netty.lesson11.pipeLine; import java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; 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; /** * 消息傳遞 */ public class Server { public static void main(String[] args) { //服務類 ServerBootstrap bootstrap = new ServerBootstrap(); //boss線程監聽端口,worker線程負責數據讀寫 ExecutorService boss = Executors.newCachedThreadPool(); ExecutorService worker = Executors.newCachedThreadPool(); //設置niosocket工廠 bootstrap.setFactory(new NioServerSocketChannelFactory(boss, worker)); //設置管道的工廠 bootstrap.setPipelineFactory(new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline pipeline = Channels.pipeline(); pipeline.addLast("handler1", new MyHandler1()); pipeline.addLast("handler2", new MyHandler2()); return pipeline; } }); bootstrap.bind(new InetSocketAddress(51503)); System.out.println("start!!!"); } }
3、MyHandler1.java
package com.example.netty.lesson11.pipeLine; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.channel.UpstreamMessageEvent; public class MyHandler1 extends SimpleChannelHandler { @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { ChannelBuffer buffer = (ChannelBuffer)e.getMessage(); byte[] array = buffer.array(); String message = new String(array); System.out.println("handler1:" + message); //傳遞給handler2 ctx.sendUpstream(new UpstreamMessageEvent(ctx.getChannel(), "abc", e.getRemoteAddress())); ctx.sendUpstream(new UpstreamMessageEvent(ctx.getChannel(), "efg", e.getRemoteAddress())); } }
4、MyHandler2.java
package com.example.netty.lesson11.pipeLine; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; public class MyHandler2 extends SimpleChannelHandler { @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { String message = (String)e.getMessage(); System.out.println("handler2:" + message); } }
完畢!