V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
liuminghao233
V2EX  ›  问与答

加密 tcp 传输解决粘包有没有好的解决方法

  •  
  •   liuminghao233 · 2017-07-06 01:25:28 +08:00 · 3562 次点击
    这是一个创建于 2726 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用 aes cfb 加密

    我的想法是这样

    包头放一个 unaigned short 表示长度
    包尾放一个 char 表示结束


    包的长度缺失会导致数据解不完全

    收到首包先 decrypt 获取包标记的长度
    残包则不 decrypt
    所以现在有这些情况
    1.首包完整
    2.首包长度少了 标记残包
    3.首包长度多了 标记 copy 出残包 处理完整的包
    标记残包后又接受新包后出现:
    4.还是残包
    5.长度多了 重复 3
    6.刚好 处理掉 等下一首包

    问题来了,如果首包收到 1byte 的话,那就连长度都不知道了,处理起来简直爆炸。
    各位大神有没有屌一点的解决思路?
    12 条回复    2017-07-13 14:02:32 +08:00
    xenme
        1
    xenme  
       2017-07-06 01:52:50 +08:00 via iPhone
    来多少收多少。

    然后根据长度,序号来处理就好了。
    yangff
        2
    yangff  
       2017-07-06 01:58:28 +08:00
    tcp 是流啊……
    XiaoxiaoPu
        3
    XiaoxiaoPu  
       2017-07-06 01:58:38 +08:00
    TCP 是流(stream),怎么会粘包(packet)。设计 TCP 上的通信协议一定不要带着包这个概念。你看 HTTP 协议里,都是用特殊的内容(\r\n 或空行等等)来标记一个结构的结束,从来没提过“包”。
    senghoo
        4
    senghoo  
       2017-07-06 07:46:59 +08:00 via iPad
    做缓冲区,收到的全部扔缓冲区,然后根据包头获取指定长度,剩下的留着当作下个包。
    sleshep
        5
    sleshep  
       2017-07-06 09:30:31 +08:00
    我读 4 字节,不够再读,大小不久得到了?
    yxaaa123
        6
    yxaaa123  
       2017-07-06 09:37:21 +08:00
    几年前有次面试时候面试题里面看到『如何处理 TCP 的粘包问题?』的问题,那时候对网络完全不懂,后来在网上找这方面的答案,也找到了。其实很多人都把这种情况称为粘包。。。
    qq292382270
        7
    qq292382270  
       2017-07-06 09:37:48 +08:00
    会分包但是不会乱序. 所以可以一直接收数据,直到在数据里面拿到完整的就好了..
    liuminghao233
        8
    liuminghao233  
    OP
       2017-07-06 09:56:31 +08:00 via iPhone
    毕竟要区分数据 每段数据长度不同 于是就把每段数据当成包了
    monsterxx03
        9
    monsterxx03  
       2017-07-06 09:59:29 +08:00   ❤️ 1
    第一次看到粘包这词我也很费解,tcp 哪来的 packet 概念, 后来才反应过来他们是指应用层协议的包。
    colincat
        10
    colincat  
       2017-07-06 10:00:05 +08:00 via iPhone
    1.什么是 TCP 粘包与拆包

    首先 TCP 是一个"流"协议,犹如河中水一样连成一片,没有严格的分界线。当我们在发送数据的时候就会出现多发送与少发送问题,也就是 TCP 粘包与拆包。得不到我们想要的效果。

    所谓粘包:当你把 A,B 两个数据从甲发送到乙,本想 A 与 B 单独发送,但是你却把 AB 一起发送了,此时 AB 粘在一起,就是粘包了

    所谓拆包: 如果发送数据的时候,你把 A、B 拆成了几份发,就是拆包了。当然数据不是你主动拆的,是 TCP 流自动拆的



    2.TCP 粘包与拆包产生原因

    1.进行了 MSS 大小的 TCP 分段
    2.以太网帧的 plyload 大与 MTU 进行了 IP 分片
    3.应用程序 write 写入的字节大小大于套接口发送的缓冲区大小



    3.解决方法

    1.消息定长,比如把报文消息固定为 500 字节,不够用空格补位

    2.在包尾增加回车换行符进行分割,例如 FTP 协议

    3.将消息分为消息头和消息体,消息头中包含表示消息总长度的字段


    可以使用 varint 不固定包头
    ldbC5uTBj11yaeh5
        11
    ldbC5uTBj11yaeh5  
       2017-07-06 10:01:54 +08:00
    liuminghao233
        12
    liuminghao233  
    OP
       2017-07-13 14:02:32 +08:00 via iPhone
    写了半个月终于把 ss 写出来了ˊ_>ˋ
    其实不算很难
    sock5-relay-relayserver-sock5 这个模型中考虑的东西稍微有点多

    速度还是很给力的本地跑满 100m 没问题 2333
    谢谢各位大佬
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2751 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 10:00 · PVG 18:00 · LAX 02:00 · JFK 05:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.