zoukankan      html  css  js  c++  java
  • TCP包问题

    拆包和组包

    TCP协议能够将要传输的数据拆成若干个数据包,并在保证数据包的传输顺序的前提下发送到远程主机,并组装回原来的样子。

    例子如下:

     当包1.0.0很大,会发现2.0.0数据包发送被延迟了,如果数据包1.0.0发送失败,会导致整个请求发送失败。

    为了避免如上情况发生,我们将1.0.0包拆成更小的包放入发送队列,并在接收时将这些包组装还原。效果如下所示。

     如图所示,我们将原来的1.0.0拆分成了1.1.0+1.2.0+1.3.0+1.4.0,使其他的数据包有机会插入到其中得以传输,而不至于等整个请求的数据传输完成。这一改进适用于对传输的时候又一定限制,且需要兼顾公平的场景。另外如果请求某个数据包在传输过程中出现失败,就可以从失败的数据包开始继续传输,这适用于需要断点续传的场景。

    断包和粘包

    TCP协议会根据包的大小对要传输的数据切分或合并发送(Nagle算法)。因此,同一个TCP数据包中就可能包含我们自定义的多个数据包的内容,可能是小的数据包一次发送,大的数据包切分后分配发送。

    如图:缓冲区中是完整的数据包1和只有一半的应用数据包2,TCP连接正在传输的是应用数据包2、3、4、5,一共分装为3个TCP数据包,分3次发送。

    应用程序首次从缓冲区读取数据只有包1和一半的包2,不考虑拆分的情况,包2断掉了,被称为断包。

    第二次从缓冲区读取时,将读到应用数据包2的后半部分、应用数据包3、4和应用数据包5的一部分,。应用数据包3、4是完整的,但是看上去数据包4粘在数据包3后面,称为粘包。

    应用从Socket读取数据时,实际是将数据从操作系统的缓冲区读取到应用程序的缓冲区。因此即使我们使用TCP NODELAY算法禁止TCP应用Nagle算法来合并发送数据包,也不能保证接收方不出现粘包现象。

    封包技术可以解决如上问题:给数据加入数据头和数据尾标示,以明确每个数据包的开始和结尾。

    数据包结构

    • 数据包ID:所属数据包ID。
    • 序号:分包的序号。
    • 分包大小:此分包的数据长度。
    • 数据段:实际的数据内容。
  • 相关阅读:
    【转】java内存溢出的场景及解决办法
    系统架构
    【转】Linux tar命令详解
    【转】Java 开发必会的 Linux 命令
    【转】ps命令详解与使用
    【转】Linux命令:ps -ef |grep java
    linux grep命令详解
    【springcloud】Zuul 超时、重试、并发参数设置
    【springcloud】常见面试题总结
    php的函数应用
  • 原文地址:https://www.cnblogs.com/wangb0402/p/12674563.html
Copyright © 2011-2022 走看看