• c++ 网络编程与协议的设计方法


    1.TCP协议的粘包问题

    TCP协议发送的是字节流,前后之间的间隔在哪里是不确定的,所有有可能出现粘包现象。

    解决粘包问题主要有三个办法

    (1).发送固定长度的包,这样接受方也接受固定长度,很显然这种办法很死板。

    (2).指定字符串位为包的结束标志。这种方法有FTP和SMPT协议采用。

    (3).使用包头+包体的方法。这种格式的包一般分为两个部分,包头和包体,包头是固定大小的,且包头必须包含一个字段来说明接下来的包体有多大。比如:

    struct msg_header{

            int32_t bodysize;//指定包头的大小

            int32_t cmd;

    };

    这样包头的大小是固定的,为sizeof(struct msg_header),协议中需要先接受包头的大小,然后解析包头,根据解析出来的信息,来接受后面的包体,这样就组成了一个完整的包来处理。

    2.解包和处理

           如果协议是包头+包体的方式(其他两种方式其实也一样)

           收到数据后,先接受包头,判断数据是否是包头大小,如果没有,则退出;如果有,则解析包头,计算接下来需要接受包体的大小。接受数据,判断数据是否达到要求,如果没有则退出,如果有则解析包体。

           这里面有一些细节问题,比如取出包头不要把包头从缓存区中取出来,而是复制出来,因为如果剩余的空间不足以存放包体大小,我们还得做扩充处理,然后把包体放回去。也就是说,我们每次取出数据的时候,最好是把包体和包头一起取出来,清空缓存。

         接受包头,解析包体要放在一个循环体里面!因为包太多,我们没办法同时处理多个包。

    3.TLV

    如果我们使用struct方法来处理TLV,则会发生格式过于死板的问题,后续版本的更新会很难进行。为了兼容版本,同时节省空间,获得更加灵活的协议,于是出现了TLV(type length value)协议,就是再每一个字段前面加一个类型字段。

    struct msg_TLV{

            short type1;

            int version;

            short type2;

            char name[10];

    };

    这样我们可以根据type来判断后面的字段,协议就变得十分灵活

    缺点就是多了一个类型字段,占据的空间变大了,还要判断类型,解析后面的信息。

  • 相关阅读:
    Spring笔记框架
    MyBatis的缓存
    戏说领域驱动设计(二十)——值对象
    在昇腾平台上对TensorFlow网络进行性能调优
    【C/C++】malloc/free 和 new/delete
    2023美亚杯个人赛复盘(三)
    SSM毕业设计管理系统
    互联网Java工程师面试题·Java 总结篇·第二弹
    利用ChatGPT完成2024年MathorCup大数据挑战赛-赛道A初赛:台风预测与分析
    Java23种设计模式-结构型模式之适配器模式
  • 原文地址:https://blog.csdn.net/weixin_42581560/article/details/133955492