zoukankan      html  css  js  c++  java
  • tcp粘包和拆包问题,以及封包和解包方案

    参考:

    workerman框架协议源码

    https://blog.csdn.net/msdnwolaile/article/details/50769708 (tcp粘包问题经典分析)

    https://wiki.swoole.com/#/learn?id=tcp粘包问题 (swoole文档)

    粘包与拆包的概念

    TCP是基于字节流的,只维护发送出去多少,确认了多少,并没有维护消息与消息之间的边界;

    在TCP/IP协议中,由于传输层并不了解应用层数据的含义,发送端传输层可能会对应用层数据进行拆分或者合并,在接收端也同样如此。由此而产生的问题就是常常会听说的“粘包与拆包”的问题。“粘包拆包”的问题在“短报文”和“一问一答”的场景下其实并不会出现。短报文是指报文长度远小于MSS的情况,应用层的报文在TCP报文中完全可以放下。另一方面,“一问一答”的通信模式可以保证报文会以单一的TCP包发送出去。在这两个条件下都满足时,我们不需要考虑“粘包拆包”问题。

    反之,如果这两个条件不同时满足,就很可能会出现“粘包拆包”问题。

    粘包拆包的问题的原因大概有以下几个方面:

    • 应用程序要写入的报文字节数大于套接字缓存区大小,这时候会发生拆包问题。
    • 应用程序的报文字节数小于套接字缓冲区大小,但应用程序连续写入多个数据包,这会导致粘包问题。
    • TCP缓冲区的数据比较多,传输层根据MSS对缓冲区的数据进行分片发送。
    • 接收时不及时读取套接字缓冲区的数据

    问题描述,上图

    解决方法有三种,具体如下:

    1,发送端给每个数据包添加包首部,首部长度应该至少包含数据包的长度 ;

    2,固定每次发送的报文长度,不够用0补充;

    3,约定好包的边界,添加首部尾部标识,如特许字符;

    关键方法

    1,输入的判断

    目的是返回包长

    2,封包方法

    3,解包方法

    4,重要函数和字符

    pack(format,arg):将参数打包成二进制字符串

    unpack(format,arg):从二进制解析出字符串

    ord() 返回字符的ASCII码值

    chr() ASCII码值对应的字符,与ord互补
    strlen:字符串长度 substr:从某个位置开始截取 strpos:特殊边界字符判断 trim/rtrim/ltrim:去除特殊边界字符
  • 相关阅读:
    python学习笔记 async and await
    python学习笔记 异步asyncio
    python学习笔记 协程
    python学记笔记 2 异步IO
    python学习笔记 可变参数关键字参数**kw相关学习
    逆波兰表达式 栈表达式计算
    Codeforces 270E Flawed Flow 网络流问题
    Codeforces 219D Choosing Capital for Treeland 2次DP
    kuangbin 带你飞 概率期望
    函数式编程思想:以函数的方式思考,第3部分
  • 原文地址:https://www.cnblogs.com/tkzc2013/p/14445250.html
Copyright © 2011-2022 走看看