粘包问题

粘包是指发送方发送的两个或多个包到接收方时,由于包的发送时间间隔太短,或者包的大小太小,导致这些包在接收方粘在一起,无法区分。

Netty提供了DelimiterBasedFrameDecoderLengthFieldBasedFrameDecoder等解码器来解决粘包问题。

  • DelimiterBasedFrameDecoder:基于分隔符的解码器。如果你的协议中有固定的分隔符,你可以使用这个解码器来切割消息。
  • LengthFieldBasedFrameDecoder:基于长度字段的解码器。如果你的协议中每个消息前都有长度字段,你可以使用这个解码器来切割消息。

丢包问题

丢包是指在网络传输过程中,数据包由于各种原因(如网络拥塞、设备故障等)未能到达接收方。

对于丢包问题,Netty并没有直接提供解决方案,因为丢包是底层网络传输的问题,Netty主要关注在应用层的数据处理。但是,你可以通过一些策略来减少丢包的可能性,例如:

  1. 重试机制:在发送方,如果数据包在一定时间内未得到确认,可以重新发送该数据包。
  2. 心跳机制:定期发送心跳包,以检查连接的活性。如果接收方在一段时间内没有收到心跳包,可以认为连接已断开,此时发送方可以选择重新连接并重新发送数据包。
  3. 流量控制:通过TCP的滑动窗口机制进行流量控制,避免网络拥塞导致的丢包。

编码处理Demo:

package com.zdzl.zzh.common;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
 * 服务端发送内容给客户端进行编码--->客户端
 * @author jjy
 * @date 2018年10月11日
 */
public class NettyEncoder extends MessageToByteEncoder<byte[]> {

	@Override
	protected void encode(ChannelHandlerContext ctx, byte[] msg, ByteBuf out) throws Exception {
		out.writeBytes(msg);
	}



}


解码处理Demo:

package com.zdzl.zzh.common;

import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

/**
 * 废弃采用LineBasedFrameDecoder
 * 收到客户端传来的数据进行解码处理-->服务端
 * 
 * @author jjy
 */
public class NettyDecoder extends ByteToMessageDecoder {

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List<Object> out) throws Exception {
		buf.markReaderIndex(); // 我们标记一下当前的readIndex的位置
		int dataLength = buf.readInt(); // 读取传送过来的消息的长度。ByteBuf 的readInt()方法会让他的readIndex增加4
		if (dataLength < 0) { // 我们读到的消息体长度为0,这是不应该出现的情况,这里出现这情况,关闭连接。
			ctx.close();
		}
		if (buf.readableBytes() < dataLength) { // 读到的消息体长度如果小于我们传送过来的消息长度,则resetReaderIndex. 个配合markReaderIndex使用的。把readIndex重置到mark的地方
			buf.resetReaderIndex();
			return;
		}
		byte[] body = new byte[dataLength]; // 这时候,我们读到的长度,满足我们的要求了,把传送过来的数据,取出来吧~~
		buf.readBytes(body); //
		Object o = new String(body); // 将byte数据转化为我们需要的对象。伪代码,用什么序列化,自行选择
		out.add(o);
	}

}