• 应用层如何感知传输层链路故障


    应用层如何感知传输层链路故障

    比如,一条普通的http连接底层依赖了一条普通的tcp连接,当某些故障导致tcp断掉了,http如何感知呢?

    结论:tcp连接本质上是逻辑上的连接,依靠两边的操作系统内核维护了一些变量来表示连接的不同状态,所以只有在两端间真正有数据包传送的时候,才可能会改变现有的逻辑状态到一个新状态。

    以下实验已将socket keepalive关闭

    实验1:应用层有新数据发送时

    实验过程

    1. client 与 server 建立TCP连接

    2. 通过scapy构造RST包“欺骗”server关闭连接来模拟链路故障,此时client并不知情server端已关闭(send(IP(dst=“192.168.57.3”)/TCP(sport=42752, dport=12345, seq=992635624, flags=“R”)))

    3. client发送数据

    4. 可以看到server由内核代为返回了RST包

    抓包详情如下:

    在这里插入图片描述

    其中称192.168.57.100为client,192.168.57.3为server

    每个包解释如下:

    • seq=1-3,TCP三次握手建立连接

    • seq=12,用scapy构造的欺骗包,让server误以为client要断开连接,从而server释放掉该tcp连接

    • seq=13,client认为连接仍然正常,使用send()函数发送字符串"hello world"给server

    • seq=14,server端内核发现13号数据包对应的socket不存在,遂发送RST包提示对方该连接无效,也就是14号包

    实验2:应用层要接受数据

    实验过程

    1. client 与 server 建立TCP连接

    2. 通过scapy构造RST包“欺骗”server关闭连接来模拟链路故障,此时client并不知情server端已关闭

    3. client 进入 recv开始阻塞接收

    4. 实验效果:client一直阻塞在recv处

    抓包详情如下:

    在这里插入图片描述

    可以看到在发送seq=20的RST欺骗包后,随后双方无任何数据沟通。导致了server端TCP连接已关闭,但client端不知情,一直阻塞。

    这里的“client端不知情”说的稍微明白些其实是“client 的内核不知情”,如果在“内核知情后”,再进入recv,会有什么效果呢?

    实验3:应用层发送数据后再接收数据

    开篇提到的http是比较符合这种情况的,因为http是由request(发送数据)和response(接受数据)构成的

    实验过程

    1. client 与 server 建立TCP连接

    2. 通过scapy构造RST包“欺骗”server关闭连接来模拟链路故障,此时client并不知情server端已关闭

    3. client发送数据

    4. client接收数据

    5. 实验效果:send发送返回成功,recv返回“Connection reset by peer”

    抓包详情:

    在这里插入图片描述

    数据包情况跟实验1完全一致,client发送了15号数据包,server返回16号RST包通知到client内核,待到client执行recv时,内核直接返回“Connection reset by peer”的信息提示应用层。

  • 相关阅读:
    [Linux] CentOS 7图形化界面——安装配置
    数字化转型迈向深水区:银行业不断夯实科技根基
    swagger-03-文档注释使用
    大数据周会-本周学习内容总结017
    微信测试号推送
    关于消息队列的那些事
    【Quark RISC-V】流水线CPU设计(4)数据冒险的处理(主要解决方案:流水线暂停、数据转发、乱序执行)
    kubesphere3.4.1不同等级告警发送至不同邮箱
    scipy库统计模块stats
    Python运维学习Day01-文件基本操作
  • 原文地址:https://blog.csdn.net/qq_35362055/article/details/126685994