IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Tcp粘包拆包解决之道 -> 正文阅读

[网络协议]Tcp粘包拆包解决之道

Tcp粘包拆包解决之道

原因:为什么会粘包,为什么需要拆包?

Tcp是个“流”协议,并没有指定的分界线,一个包,可能会被Tcp拆分成多个包发送,也可能将多个小包,封装成一个

大的数据包发送

首先,据计算机网络中概述

  1. Tcp提供全双工通信,在Tcp的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据,发送时,应用程序把数据发送给发送缓冲区,应用程序发送工作完成,接收时,Tcp将接收到的数据放入接收缓冲区,应用程序到合适的时候读取
  2. Tcp的数据流,是一串字节序列,虽然和应用程序的交互,是一次一个数据块,但是Tcp将交互的数据,看做是一串无结构的字节流。Tcp不保证接收方应用程序所收到的数据块和发送方的数据块具有对应大小的关系(例如:发送方应用程序交给发送方的Tcp共10个数据块,但是接收方的Tcp可能仅用了4个数据块就把接收到的字节流交付给上层的应用程序,也就是说,你寄了10个快递给老A,但是10个快递被物流公司用4个纸盒给你装起来了,老A收到的就是4个纸盒)。所以,老A需要将4个快递盒全部拆分,还原成10个快递,才是你发给老A的东西
  3. 在Tcp的通信过程中,都是面临者缓冲区进行数据的IO,所以,如果应用程序发送的数据过大,将缓冲区比喻为一个大号快递盒,那么就需要将应用程序发送的数据包进行部分拆分,然后发送出去(当然和快递有区分,有的快递拆不了,但是应用程序发送的所有数据,是都转成了字节序列的),这就是Tcp拆包
  4. Tcp的通信,虽然是以字节序列进行传输,但是Tcp的数据单元却是报文段,一个Tcp的报文段分为首部和数据两部分,而且,Tcp的报文段,是有最大长度的,成为MSS,它是指数据部分的最大长度,所以,当进行了MSS大小的分段时,一刀切下去,原有的数据就肯定不在一个数据段内了
  5. 假如,应用程序连续发送了两个数据包,但是这个两个数据包加在一起既没有超过缓冲区大小,又不超过一个Tcp段的大小,那么,这两个数据包就发生了Tcp粘包
  6. 在TCP通讯协议中TCP的每个包头的长度都是固定的,总长度不能超过MTU(最大传输单元),且数据长度不能超过MSS(MSS=MTU-20bytes(IP包头)-20bytes(TCP包头))。如果超过了MTU系统会进行拆包处理。

在这里插入图片描述

常见的解决策略

  1. 消息定长,例如每个报文的大小为固定长度的200字节,如果不够,空位补空格
  2. 在包尾增加回车换行符进行分割,例如FTP协议
  3. 将消息分为消息头和消息体,消息头中包含消息总长度的字段,通常设计思路为消息头的第一个字段使用int32来表示消息的总长度
  4. 更复杂的应用层协议

未考虑Tcp粘包导致功能异常的样例

服务端代码

package com.su.netty;

import com.su.bio.BioTest;
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;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @ClassName:NettyTimeServer
 * @Author: sz
 * @Date: 2022/8/23 17:37
 * @Description:
 */

public class NettyTimeServer {
    public static void main(String[] args) throws Exception {
        int port = 8080;
        if(args !=null && args.length>0){
            try {
                port = Integer.parseInt(args[0]);
            }catch (Exception e){

            }
        }
        new NettyTimeServer().bind(port);

    }

    public void bind(int port) throws Exception{
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG,1024)
                    .childHandler(new ChildChannelHandler());
            //绑定端口 同步等待成功
            ChannelFuture f = b.bind(port).sync();
            
            //等待服务端监听端口关闭
            f.channel().closeFuture().sync();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    
    private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{

        @Override
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            socketChannel.pipeline().addLast(new TimeServerHandler());
        }
    }
}

服务端Handler代码

package com.su.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Date;

/**
 * @ClassName:TimeServerHandler
 * @Author: sz
 * @Date: 2022/8/23 17:55
 * @Description:
 */

public class TimeServerHandler extends ChannelInboundHandlerAdapter {
    private int counter;
    @Override
    public void channelRead(ChannelHandlerContext ctx , Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        byte[] req = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(req);
        String body = new String(req,"UTF-8").substring(0,req.length -  System.getProperty("line.separator").length());
        System.out.println("The time server receive order :"+body + "; the counter is "+ ++counter);
        String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString() : "BAD ORDER";
        currentTime = currentTime + System.getProperty("line.separator");
        ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
        ctx.write(resp);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx ){
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx , Throwable cause){
        ctx.close();
    }
}

客户端代码

package com.su.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * @ClassName:NettyTimeClient
 * @Author: sz
 * @Date: 2022/8/23 18:24
 * @Description:
 */

public class NettyTimeClient {

    public static void main(String[] args) throws Exception {
        int port = 8080;
        if(args !=null && args.length>0){
            try {
                port = Integer.parseInt(args[0]);
            }catch (Exception e){

            }
        }
        new NettyTimeClient().connect(port,"127.0.0.1");

    }

    public void connect(int port ,String host)throws Exception{
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY,true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel channel) throws Exception {
                            channel.pipeline().addLast(new TimeClientHandler());
                        }
                    });
            ChannelFuture f = b.connect(host,port).sync();
            f.channel().closeFuture().sync();

        }catch (Exception e){
            group.shutdownGracefully();

        }
    }
}

客户端Hanlder

package com.su.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.Date;

/**
 * @ClassName:TimeClientHandler
 * @Author: sz
 * @Date: 2022/8/23 18:30
 * @Description:
 */

public class TimeClientHandler extends ChannelInboundHandlerAdapter {
    private int counter;

    private byte[] req ;
    public TimeClientHandler(){
         req = ("QUERY TIME ORDER" + System.getProperty("line.separator")).getBytes();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx){
        ByteBuf message = null;
        for (int i =0 ;i<100; i++){
            message = Unpooled.buffer(req.length);
            message.writeBytes(req);
            ctx.writeAndFlush(message);
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx , Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        byte[] req = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(req);
        String body = new String(req,"UTF-8");
        System.out.println("Now is :"+body+";the counter is :"+ ++counter);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx ){
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx , Throwable cause){
        ctx.close();
    }
}

运行结果

服务端

The time server receive order :QUERY TIME ORDER; the counter is 1
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 2
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 3
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 4
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 5
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 6
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 7
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 8
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 9
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 10
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 11
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 12
The time server receive order :QUERY TIME ORDER; the counter is 13
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 14
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 15
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 16
The time server receive order :QUERY TIME ORDER; the counter is 17
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 18
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 19
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 20
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 21
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 22
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 23
The time server receive order :QUERY TIME ORDER; the counter is 24
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 25
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 26
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 27
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 28
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 29
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 30
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 31
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 32
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER; the counter is 33
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 34
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 35
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 36
The time server receive order :QUERY TIME ORDER
QUERY TIME ORDER
QUERY TIME ORDER; the counter is 37

客户端:

BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
Thu Sep 15 10:48:10 CST 2022
BAD ORDER
BAD ORDER
BAD ORDER
Thu Sep 15 10:48:10 CST 2022
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
Thu Sep 15 10:48:10 CST 2022
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
BAD ORDER
;the counter is :1

结论

服务端的运行结果表明收到了37条消息,但是却包含100条QUERY TIME ORDER,发生了粘包。由于消息不等于QUERY TIME ORDER,所以客户端收到的是Bad Order,但是客户端也只收到了一条消息,说明服务端的应答消息也发生了Tcp粘包

编解码器解决粘包问题

netty提供了多种编解码器处理粘包拆包问题

服务端代码

package com.su.netty;

import com.su.bio.BioTest;
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;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

/**
 * @ClassName:NettyTimeServer
 * @Author: sz
 * @Date: 2022/8/23 17:37
 * @Description:
 */

public class NettyTimeServer {
    public static void main(String[] args) throws Exception {
        int port = 8080;
        if(args !=null && args.length>0){
            try {
                port = Integer.parseInt(args[0]);
            }catch (Exception e){

            }
        }
        new NettyTimeServer().bind(port);

    }

    public void bind(int port) throws Exception{
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG,1024)
                    .childHandler(new ChildChannelHandler());
            //绑定端口 同步等待成功
            ChannelFuture f = b.bind(port).sync();
            
            //等待服务端监听端口关闭
            f.channel().closeFuture().sync();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
    
    private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{

        @Override
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024));
            socketChannel.pipeline().addLast(new StringDecoder());
            socketChannel.pipeline().addLast(new TimeServerHandler());
        }
    }
}

服务端hanlder

package com.su.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Date;

/**
 * @ClassName:TimeServerHandler
 * @Author: sz
 * @Date: 2022/8/23 17:55
 * @Description:
 */

public class TimeServerHandler extends ChannelInboundHandlerAdapter {
    private int counter;
    @Override
    public void channelRead(ChannelHandlerContext ctx , Object msg) throws Exception {
        String body = (String) msg;
        System.out.println("The time server receive order :"+body + "; the counter is "+ ++counter);
        String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString() : "BAD ORDER";
        currentTime = currentTime + System.getProperty("line.separator");
        ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
        ctx.write(resp);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx ){
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx , Throwable cause){
        ctx.close();
    }
}

客户端代码

package com.su.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

/**
 * @ClassName:NettyTimeClient
 * @Author: sz
 * @Date: 2022/8/23 18:24
 * @Description:
 */

public class NettyTimeClient {

    public static void main(String[] args) throws Exception {
        int port = 8080;
        if(args !=null && args.length>0){
            try {
                port = Integer.parseInt(args[0]);
            }catch (Exception e){

            }
        }
        new NettyTimeClient().connect(port,"127.0.0.1");

    }

    public void connect(int port ,String host)throws Exception{
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY,true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel channel) throws Exception {
                            channel.pipeline().addLast(new LineBasedFrameDecoder(1024));
                            channel.pipeline().addLast(new StringDecoder());
                            channel.pipeline().addLast(new TimeClientHandler());
                        }
                    });
            ChannelFuture f = b.connect(host,port).sync();
            f.channel().closeFuture().sync();

        }catch (Exception e){
            group.shutdownGracefully();

        }
    }
}

客户端handler

package com.su.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.Date;

/**
 * @ClassName:TimeClientHandler
 * @Author: sz
 * @Date: 2022/8/23 18:30
 * @Description:
 */

public class TimeClientHandler extends ChannelInboundHandlerAdapter {
    private int counter;

    private byte[] req ;
    public TimeClientHandler(){
         req = ("QUERY TIME ORDER" + System.getProperty("line.separator")).getBytes();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx){
        ByteBuf message = null;
        for (int i =0 ;i<100; i++){
            message = Unpooled.buffer(req.length);
            message.writeBytes(req);
            ctx.writeAndFlush(message);
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx , Object msg) throws Exception {

        String body = (String) msg;
        System.out.println("Now is :"+body+";the counter is :"+ ++counter);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx ){
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx , Throwable cause){
        ctx.close();
    }
}

运行结果

服务端接收

The time server receive order :QUERY TIME ORDER; the counter is 1
The time server receive order :QUERY TIME ORDER; the counter is 2
The time server receive order :QUERY TIME ORDER; the counter is 3
The time server receive order :QUERY TIME ORDER; the counter is 4
The time server receive order :QUERY TIME ORDER; the counter is 5
The time server receive order :QUERY TIME ORDER; the counter is 6
The time server receive order :QUERY TIME ORDER; the counter is 7
The time server receive order :QUERY TIME ORDER; the counter is 8
The time server receive order :QUERY TIME ORDER; the counter is 9
The time server receive order :QUERY TIME ORDER; the counter is 10
The time server receive order :QUERY TIME ORDER; the counter is 11
The time server receive order :QUERY TIME ORDER; the counter is 12
The time server receive order :QUERY TIME ORDER; the counter is 13
The time server receive order :QUERY TIME ORDER; the counter is 14
The time server receive order :QUERY TIME ORDER; the counter is 15
The time server receive order :QUERY TIME ORDER; the counter is 16
The time server receive order :QUERY TIME ORDER; the counter is 17
The time server receive order :QUERY TIME ORDER; the counter is 18
The time server receive order :QUERY TIME ORDER; the counter is 19
The time server receive order :QUERY TIME ORDER; the counter is 20
The time server receive order :QUERY TIME ORDER; the counter is 21
The time server receive order :QUERY TIME ORDER; the counter is 22
The time server receive order :QUERY TIME ORDER; the counter is 23
The time server receive order :QUERY TIME ORDER; the counter is 24
The time server receive order :QUERY TIME ORDER; the counter is 25
The time server receive order :QUERY TIME ORDER; the counter is 26
The time server receive order :QUERY TIME ORDER; the counter is 27
The time server receive order :QUERY TIME ORDER; the counter is 28
The time server receive order :QUERY TIME ORDER; the counter is 29
The time server receive order :QUERY TIME ORDER; the counter is 30
The time server receive order :QUERY TIME ORDER; the counter is 31
The time server receive order :QUERY TIME ORDER; the counter is 32
The time server receive order :QUERY TIME ORDER; the counter is 33
The time server receive order :QUERY TIME ORDER; the counter is 34
The time server receive order :QUERY TIME ORDER; the counter is 35
The time server receive order :QUERY TIME ORDER; the counter is 36
The time server receive order :QUERY TIME ORDER; the counter is 37
The time server receive order :QUERY TIME ORDER; the counter is 38
The time server receive order :QUERY TIME ORDER; the counter is 39
The time server receive order :QUERY TIME ORDER; the counter is 40
The time server receive order :QUERY TIME ORDER; the counter is 41
The time server receive order :QUERY TIME ORDER; the counter is 42
The time server receive order :QUERY TIME ORDER; the counter is 43
The time server receive order :QUERY TIME ORDER; the counter is 44
The time server receive order :QUERY TIME ORDER; the counter is 45
The time server receive order :QUERY TIME ORDER; the counter is 46
The time server receive order :QUERY TIME ORDER; the counter is 47
The time server receive order :QUERY TIME ORDER; the counter is 48
The time server receive order :QUERY TIME ORDER; the counter is 49
The time server receive order :QUERY TIME ORDER; the counter is 50
The time server receive order :QUERY TIME ORDER; the counter is 51
The time server receive order :QUERY TIME ORDER; the counter is 52
The time server receive order :QUERY TIME ORDER; the counter is 53
The time server receive order :QUERY TIME ORDER; the counter is 54
The time server receive order :QUERY TIME ORDER; the counter is 55
The time server receive order :QUERY TIME ORDER; the counter is 56
The time server receive order :QUERY TIME ORDER; the counter is 57
The time server receive order :QUERY TIME ORDER; the counter is 58
The time server receive order :QUERY TIME ORDER; the counter is 59
The time server receive order :QUERY TIME ORDER; the counter is 60
The time server receive order :QUERY TIME ORDER; the counter is 61
The time server receive order :QUERY TIME ORDER; the counter is 62
The time server receive order :QUERY TIME ORDER; the counter is 63
The time server receive order :QUERY TIME ORDER; the counter is 64
The time server receive order :QUERY TIME ORDER; the counter is 65
The time server receive order :QUERY TIME ORDER; the counter is 66
The time server receive order :QUERY TIME ORDER; the counter is 67
The time server receive order :QUERY TIME ORDER; the counter is 68
The time server receive order :QUERY TIME ORDER; the counter is 69
The time server receive order :QUERY TIME ORDER; the counter is 70
The time server receive order :QUERY TIME ORDER; the counter is 71
The time server receive order :QUERY TIME ORDER; the counter is 72
The time server receive order :QUERY TIME ORDER; the counter is 73
The time server receive order :QUERY TIME ORDER; the counter is 74
The time server receive order :QUERY TIME ORDER; the counter is 75
The time server receive order :QUERY TIME ORDER; the counter is 76
The time server receive order :QUERY TIME ORDER; the counter is 77
The time server receive order :QUERY TIME ORDER; the counter is 78
The time server receive order :QUERY TIME ORDER; the counter is 79
The time server receive order :QUERY TIME ORDER; the counter is 80
The time server receive order :QUERY TIME ORDER; the counter is 81
The time server receive order :QUERY TIME ORDER; the counter is 82
The time server receive order :QUERY TIME ORDER; the counter is 83
The time server receive order :QUERY TIME ORDER; the counter is 84
The time server receive order :QUERY TIME ORDER; the counter is 85
The time server receive order :QUERY TIME ORDER; the counter is 86
The time server receive order :QUERY TIME ORDER; the counter is 87
The time server receive order :QUERY TIME ORDER; the counter is 88
The time server receive order :QUERY TIME ORDER; the counter is 89
The time server receive order :QUERY TIME ORDER; the counter is 90
The time server receive order :QUERY TIME ORDER; the counter is 91
The time server receive order :QUERY TIME ORDER; the counter is 92
The time server receive order :QUERY TIME ORDER; the counter is 93
The time server receive order :QUERY TIME ORDER; the counter is 94
The time server receive order :QUERY TIME ORDER; the counter is 95
The time server receive order :QUERY TIME ORDER; the counter is 96
The time server receive order :QUERY TIME ORDER; the counter is 97
The time server receive order :QUERY TIME ORDER; the counter is 98
The time server receive order :QUERY TIME ORDER; the counter is 99
The time server receive order :QUERY TIME ORDER; the counter is 100


客户端接收

Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :1
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :2
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :3
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :4
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :5
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :6
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :7
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :8
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :9
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :10
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :11
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :12
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :13
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :14
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :15
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :16
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :17
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :18
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :19
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :20
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :21
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :22
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :23
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :24
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :25
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :26
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :27
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :28
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :29
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :30
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :31
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :32
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :33
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :34
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :35
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :36
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :37
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :38
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :39
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :40
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :41
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :42
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :43
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :44
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :45
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :46
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :47
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :48
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :49
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :50
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :51
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :52
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :53
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :54
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :55
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :56
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :57
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :58
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :59
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :60
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :61
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :62
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :63
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :64
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :65
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :66
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :67
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :68
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :69
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :70
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :71
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :72
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :73
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :74
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :75
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :76
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :77
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :78
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :79
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :80
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :81
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :82
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :83
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :84
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :85
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :86
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :87
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :88
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :89
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :90
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :91
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :92
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :93
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :94
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :95
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :96
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :97
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :98
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :99
Now is :Thu Sep 15 11:01:08 CST 2022;the counter is :100

结论

netty提供的LineBasedFrameDecoder,依次遍历ByteBuf中的可读字节,判断看是否有“\n”或者“\r\n”,如果有就以此位置为结束位置,从可读位置到结束位置组成一行。它是以换行符为结束标识的解码器,支持携带结束符或者不携带结束符两种解码方式,同时支持配置单行的最大长度,如果连续读取到最大长度后仍没有发现换行符,就回抛出异常,同时忽略之前读到的异常码流

StringDecoder的功能 很简单,就是将接收到的对象转换成字符串,然后继续调用后面的handler,LineBasedFrameDecoder+StringDecoder组合就是按行切换的文本解码器,它被设计用来支持Tcp的粘包和拆包

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 01:01:36  更:2022-09-21 01:03:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 7:07:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码