• TCP延迟应答和捎带应答及“粘包问题“和TCP异常


    参考数据 : TCP/IP 卷一 ,图解TCP/IP,计算机网络-自顶向下方法

    参考网站 : 4.6 如何理解是 TCP 面向字节流协议? | 小林coding

    目录

    延迟应答

    什么是延迟应答???

    为啥要有延迟应答呢??

    捎带应答

    再谈四次挥手

    面向字节流

    怎么理解面向数据报与面向字节流呢???

    粘包问题

    如何解决"粘包问题" 呢???

    TCP异常

    主机关机

    程序崩溃

    主机掉电/网线断开


    延迟应答

    什么是延迟应答???

    延迟应答就是接收方延迟一段时间接收ACK,这样应用进程就有时间来消耗接收缓冲区里面的数据,所以滑动窗口的窗口大小也变大了.这样就提高了效率.

    为啥要有延迟应答呢??

    首先延迟应答是效率机制也就是说是提高TCP的效率的,让其在没有网络故障的情况下,让其能够传输更多的数据.这样传输效率就变高了.

    每收到几个数据报就返回一个ACK,当最后没有数据报传输给接收方,达到最大延迟时间,就返回ACK

    捎带应答

    在客户端-服务器场景下,一发一收这样的场景下,可以在延迟应答的基础上更进一步提高效率.

    服务端返回给客户端ACK的时候,可以在延迟一段时间内将服务端给客户端的响应一并返回给客户端,这样就提升了效率.

    再谈四次挥手

    在延迟应答和捎带应答的机制下,四次挥手也有可能变为3次挥手.

    面向字节流

    怎么理解面向数据报与面向字节流呢???

    我以UDP和TCP协议来说明

    也就是以下我们会有两个问题

    为啥UDP是面向数据报的??? 为啥TCP是面向字节流的呢???

    • UDP面向数据报???

    使用UDP协议载传输数据时,操作系统不会将信息拆分成多个数据报发送给接收方,而是组装好UDP报头就交给了网络层,所以一个UDP报文的数据部分就是一个完整的信息.

    • 如果接收方接收到两个数据报呢??

    接收方接收到一个UDP数据报,会将其放到一个队列中去,当用户读取时就会从队列中取出一个UDP数据报从内核拷贝给接收缓冲区.

    总结 :

    使用UDP协议传输数据的时候,操作系统不会将一个信息拆分成多个数据报发送给接收方,组装好UDP报头就将其交给网络层,所以一个UDP数据报就代表一个完成的信息,接收方在接收数据报的时候,会将数据报放到一个队列中,当用户读取这个数据的时候,就会从内核中取走UDP数据报拷贝到接收缓冲区里面.

    • 如何理解TCP是面向字节流呢??

    使用TCP协议传输数据的时候,操作系统会将一个信息拆分成多个数据报发送给接收方.在传输层角度上看是面向数据报的,一个一个报文发送给接收方,但是在应用层角度上看是一个字节一个字节的数据,是面向字节流的

    粘包问题

    对于TCP面向字节流就有一个问题,使用TCP在传输数据的时候就会将数据拆分成多个数据报,如果并不知道每一条信息的长度或者是信息的边界,这样就接收方就无法读取有效的信息,好像多个数据报都粘在了一起,就是所谓的粘包问题.

    如何解决"粘包问题" 呢???

    这就需要通过应用层来去处理

    • 通过固定长度来确定消息的边界

    将每个信息都设定固定长度,每读取完一个固定长度大小的数据包,就读取了一个完整的信息.

    • 通过标识符来确定信息的边界

    给每一条信息的后面都加上特殊符号,读取到特殊符号就代表读取了一条完整的信息,如果信息里面有特殊符号就需要进行转义,避免提前读取完一个无效的数据信息

    • 通过自定义信息结构

    需要自定义一个数据报,包括包头长度和包数据,每次读取只读取每一个数据报的包头长度那么长,就读取了一个有效的数据.

    TCP异常

    有以下几种场景 : 主机关机,程序崩溃,主机掉电,网线断开.

    主机关机

    如果主机关机就会杀死用户的所有进程,杀死进程也就会释放pcb,释放文件描述符表对应的文件资源,接着触发FIN,开起了四次挥手,如果在主机关机之前完成了四次挥手就正常关闭主机,主机关闭之前还没有完成四次挥手,那么就重发FIN,多次重发后,没有响应就放弃重传,主机关闭

    程序崩溃

    程序崩溃也代表进程没了,也会释放文件描述符表对应的文件资源,就会开启四次挥手流程,由于TCP连接是操作系统内核来完成的,所以就会继续完成四次挥手过程

    主机掉电/网线断开

    主机掉电与网线断开是一样的效果

    • 接收方掉电/接收方网线断开

    如果接收方掉电/网线断开,发送方发送数据没有接收到ACK,就会重传数据,超过最大重传次数,还是没有接收到ACK,就会尝试重新连接,重新连接之后还是没有响应,那么就放弃连接.彻底放弃了.

    • 发送方掉电/网线断开

    如果发送方掉电/网线断开,接收方没有收到发送方发送的数据报,无法判定是发送方出问题了,还是数据报丢失,所以接收方会不定期的就会给发送方发送"心跳包",心跳包有特殊的报文ping,如果发送方还存活就会给接收方返回一个特殊的报文pong,这就证明发放还存活,否则发送方就挂了.

  • 相关阅读:
    muduo源码剖析之SocketOps类
    【WFA】 VHT-5.2.27 Pre-requisite throughput lower than expected
    电脑重装系统后Win11用户名怎么更改
    CS专业导论总结
    【毕业设计】深度学习社交安全距离检测系统 - python opencv
    交流回馈老化测试负载的应用
    基于ZYNQ-7000的AI加速器设计之Python网络编程(TCP协议)
    密度聚类与层次聚类
    Redis核心结构以及渐进式扩容
    山东大学人工智能导论实验二 前向传播和反向传播
  • 原文地址:https://blog.csdn.net/m0_61210742/article/details/126764964