一.TCP粘包/拆包问题说明
TCP是个“流”协议,就是没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包拆分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。
二.利用LinedBasedFrameDecoder解决TCP粘包问题
为了解决TCP粘包/拆包导致的半包读写问题,netty默认提供了多种解码器用于处理半包,只要能熟练掌握这些类库使用,TCP粘包问题就会非常容易。
2.1 支持TCP粘包的服务端开发
2.1.1 TimeServer实现:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
importio.netty.channel.nio.NioEventLoopGroup;
importio.netty.channel.socket.SocketChannel;
importio.netty.channel.socket.nio.NioServerSocketChannel;
importio.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
/*
* 利用LineBasedFrameDecoder解决TCP粘包问题
*/
public class TimeServerNoStick {
publicvoid bind(int port) throws Exception{
//配置服务端的NIO线程组
EventLoopGroupbossGroup =new NioEventLoopGroup();
EventLoopGroupworkerGroup =new NioEventLoopGroup();
try{
//用于启动NIO服务器的辅助启动类,降低服务端的开发复杂度
ServerBootstrapb=new ServerBootstrap();
b.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG,1024)
.childHandler(newChildChannelHandler());
//绑定端口,同步等待成功
ChannelFuturef=b.bind(port).sync();
//等待服务端监听端口关闭
f.channel().closeFuture().sync();
}catch (Exception e) {
//TODO: handle exception
}finally{
//优雅退出,释放线程池资源
bossGroup.shutdownGracefully();
workerG