zoukankan      html  css  js  c++  java
  • [编织消息框架][设计协议]解决粘包半包(上)

    理论部分

    网络传输是以流的方式传送,这时会出现意想不到的事

    如:发送两个消息 共8byte

    byte[] messagea=new byte[4];

    byte[] messageb=new byte[4];

    接收端: 可能会出现读两次或多次接收

    解决粘包半包有很多方式

    方式1.每条消息加结束标志:

      如 byte[] endFlag = "messageEnd".getBytes();

      messagea "+" endFlag 

    方式2.开头固定长度为消息:如先写消息长度(固定占多少byte),再写消息内容,读时先固定读长度,然后再积累内容

      byte[] len = intToBytes(messagea.length);

      len  "+" messagea

    方式1无法知道整条消息长度,而且每次接收都要与结束标志循环匹配,无法达到控制处理

    方式2能优先知道消息长度,接下来无需再匹配处理,能控且简化处理逻辑

     最终包传输以下面格式,有的长度为2或者1,有的没有校验,有的可能会加其它数据

    内容长度-4 是因为写时加上校验的固定长度,读时要减去校验长度

    源码解读

    QPacket

     1     public void writeToByteBuf(ByteBuf byteBuf) {
     2       final int packetLen = toSize(); //计算包长度
     3       byteBuf.writeShort(QMConfig.getInstance().getPacketHeadFlag(packetLen)); //写入包信息开头标志(2byte)
     4       byteBuf.writeInt(packetLen); //写入包长度(4byte)
     5       writeBytes(byteBuf);//写入内容
     6       byteBuf.writeByte(QMConfig.getInstance().getPacketEndFlag(packetLen));//写入包信息结束标志(1byte)
     7     }
     8 
     9     public int writeBytes(ByteBuf byteBuf) {
    10       byteBuf.writeLong(sn); //写入包序列
    11       byteBuf.writeShort(c); //写入opCode
    12       byteBuf.writeBytes(b); //写入消息内容
    13       byteBuf.writeLong(sid); //写入会话标识
    14       return toSize();
    15     }
  • 相关阅读:
    归档:类和对象
    归档:字符串类
    腾讯云域名解析
    Java课堂动手动脑--方法
    软件工程个人作业03——PSP记录
    软件工程个人作业03
    软件工程个人作业02——PSP0级要求记录 + 第三周进度条
    软件工程个人作业02
    第二周学习进度条
    软件工程个人作业01
  • 原文地址:https://www.cnblogs.com/solq111/p/6535112.html
Copyright © 2011-2022 走看看