追寻水中桥 2020-05-01
知识点
1、看下粘包和分包是怎么样一个情况 hello hello 通过定义一个稳定的结构 length + hello 2、buffer里面数据未被读取完怎么办? (cumulation缓存) 3、为什么return null就可以缓存buffer (cumulation缓存)
1、Client.java
package com.example.netty.lesson11.packet; import java.net.Socket; import java.nio.ByteBuffer; public class Client { public static void main(String[] args) throws Exception { /** * 会出现粘包现象,通过ByteBuffer解决粘包问题 */ Socket socket = new Socket("127.0.0.1", 51503); String message = "hello,ni hao ma?"; byte[] bytes = message.getBytes(); //4定义为包头位数 ByteBuffer buffer = ByteBuffer.allocate(4+bytes.length); buffer.putInt(bytes.length); buffer.put(bytes); byte[] array = buffer.array(); for (int i = 0; i <1000 ; i++) { socket.getOutputStream().write(array); } socket.close(); } }
2、Server.java
package com.example.netty.lesson11.packet; import com.example.netty.lesson11.pipeLine.MyHandler2; 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 java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 消息传递 */ 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("decoder", new MyDecoder()); pipeline.addLast("handler1", new MyHandler1()); return pipeline; } }); bootstrap.bind(new InetSocketAddress(51503)); System.out.println("start!!!"); } }
3、MyDecoder.java
package com.example.netty.lesson11.packet; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.handler.codec.frame.FrameDecoder; /** * @author yangwj * @date 2020/4/6 10:48 */ public class MyDecoder extends FrameDecoder { @Override protected Object decode(ChannelHandlerContext channelHandlerContext, Channel channel, ChannelBuffer buffer) throws Exception { if(buffer.readableBytes() >4){ //标记 buffer.markReaderIndex(); //长度 int length = buffer.readInt(); if(buffer.readableBytes() < length){ buffer.resetReaderIndex(); //缓存当前剩余的buffer数据,等待剩下的数据到来 return null; } //读数据 byte[] bytes = new byte[length]; buffer.readBytes(bytes); //往下传递 ,和sendUpstream类似 return new String(bytes); } //缓存当前剩余的buffer数据,等待剩下的数据到来 return null; } }
4、MyHandler1.java
package com.example.netty.lesson11.packet; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; 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); String message = (String) e.getMessage(); System.out.println("handler1:" + message); } }
完毕!