基于前8位为长度,后面为内容的需求 00000123<xml ....>,使用LengthFieldBasedFrameDecoder实现如下:
netty实现服务端,客户端为普通的socket请求
public class NettyServer {
public static void main(String[] args) {
ServerBootstrap serverBootstrap = new ServerBootstrap();
NioEventLoopGroup boos = new NioEventLoopGroup();
NioEventLoopGroup worker = new NioEventLoopGroup();
serverBootstrap
.group(boos, worker)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
protected void initChannel(NioSocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("stringEncoder",new StringEncoder(CharsetUtil.UTF_8))
.addLast("frameDecoder",
new MsgLengthFieldBasedFrameDecoder(1024*1024, 0,
8, 0, 8))
.addLast("stringDecoder", new StringDecoder(Charset.forName("UTF8")))
.addLast("messageHandler", new ServerHandler())
;
}
})
.bind(9999);
}
}
//拆包
class MsgLengthFieldBasedFrameDecoder extends LengthFieldBasedFrameDecoder {
/**
* @param maxFrameLength 解码时,处理每个帧数据的最大长度
* @param lengthFieldOffset 该帧数据中,存放该帧数据的长度的数据的起始位置
* @param lengthFieldLength 记录该帧数据长度的字段本身的长度
* @param lengthAdjustment 修改帧数据长度字段中定义的值,可以为负数
* @param initialBytesToStrip 解析的时候需要跳过的字节数
*/
public MsgLengthFieldBasedFrameDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength,int lengthAdjustment, int initialBytesToStrip) {
super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip);
}
@Override
protected long getUnadjustedFrameLength(ByteBuf buf, int offset, int length, ByteOrder order) {
if(length == 8){
buf = buf.order(order);
byte[] lengthBytes = new byte[8];
buf.readBytes(lengthBytes);
buf.resetReaderIndex();
return Integer.valueOf(new String(lengthBytes));
} else {
return super.getUnadjustedFrameLength(buf, offset, length, order);
}
}
}
public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("channelRead接收-->" + msg);
byte[] bytes = msg.toString().getBytes(CharsetUtil.UTF_8);
int length = bytes.length;
String res = "00"+String.valueOf(length) + msg; // 模拟前8位 00103961
System.out.println("返回-->" + res);
ctx.channel().writeAndFlush(res).addListener(ChannelFutureListener.CLOSE);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
}
}
package cdinit.netty.Client;
import io.netty.util.CharsetUtil;
import java.io.*;
import java.net.Socket;
public class SimpleSocketClient {
public static void main(String[] args) throws Exception {
Socket socket = null;
DataInputStream dis = null;
PrintWriter pw = null;
String msg = "";
File file = new File("C:\\Users\\admin\\Desktop\\xml.txt");
FileInputStream is = null;
StringBuilder stringBuilder = null;
try {
/**
* 文件有内容才去读文件
*/
is = new FileInputStream(file);
InputStreamReader streamReader = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(streamReader);
String line;
stringBuilder = new StringBuilder();
while ((line = reader.readLine()) != null) {
// stringBuilder.append(line);
stringBuilder.append(line);
}
msg = String.valueOf(stringBuilder);
reader.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
byte[] resBytes;
try {
socket = new Socket("127.0.0.1", 9999);
pw = new PrintWriter(socket.getOutputStream());
byte[] bytes = msg.getBytes(CharsetUtil.UTF_8);
int length = bytes.length;
String res = "00"+String.valueOf(length) + msg; // 模拟前8位
pw.write(res);
pw.flush();
// 接收
dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
byte[] resLenBytes = new byte[8]; // 读取前八位
dis.read(resLenBytes);
Integer resLen = Integer.parseInt(new String(resLenBytes,CharsetUtil.UTF_8));
resBytes = new byte[resLen]; //读取后面内容
dis.read(resBytes);
System.out.println(new String(resBytes,CharsetUtil.UTF_8));
} finally {
if(pw != null){
pw.close();
}
if(dis != null){
dis.close();
}
if(socket != null){
socket.close();
}
}
// System.out.println(new String(resBytes,CharsetUtil.UTF_8));
}
}
参考:
https://blog.csdn.net/ycllycll/article/details/92062163
https://www.sohu.com/a/259845146_575744
https://my.oschina.net/xinxingegeya/blog/282885