Netty解决粘包问题
2021-03-14 05:41
标签:hand ups 监听端口 eset class cli ide public obj 知识点 1、Client.java 2、Server.java 3、MyDecoder.java 4、MyHandler1.java 完毕! Netty解决粘包问题 标签:hand ups 监听端口 eset class cli ide public obj 原文地址:https://www.cnblogs.com/ywjfx/p/12812995.html1、看下粘包和分包是怎么样一个情况
hello hello
通过定义一个稳定的结构 length + hello
2、buffer里面数据未被读取完怎么办? (cumulation缓存)
3、为什么return null就可以缓存buffer (cumulation缓存)
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 ) {
socket.getOutputStream().write(array);
}
socket.close();
}
}
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!!!");
}
}
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;
}
}
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);
}
}