• TCP过程中,网络断开问题解决办法


    最近工作过程中,遇到了在TCP建立好连接以后,发送和接收过程中,网络断开引起的socket无法关闭的问题。

    ps:TCP的发送和接收都使用的是阻塞模式

    一、设置发送和接收的超时时间

    最开始想到的解决办法是设置发送和接收的超时时间,这样超时时间到了,发送和接收都会返回,socket就能正常关闭了。但是设置超时时间会引起其他问题。

    1、设置发送超时以后,客户端(上位机)会出现,Interrupted system call问题,产生原因是send函数在阻塞模式下,一定要等到有可用空间将send发送的数据拷贝到发送缓冲中,但是超时了,还没发送,就出现Interrupted system call。

    2、设置接收超时以后,客户端(上位机)会出现,TCP读取 [WinError 10053] 你的主机中的软件中止了一个已建立的连接问题

    二、加大发送缓冲区

    上面试验了,发送改为非阻塞行不通,所以还是改为阻塞了。既然是因为发送缓冲区太小了,导致send函数阻塞在等待可用缓冲区上了,那我直接加大发送缓冲区,让send函数能立即返回,这样send就不会阻塞了。

    1.设置socke的发送缓冲区大小,实验了不生效

    1. int sendbuf_len = (320 * 1024);
    2. setsockopt(newsockfd, SOL_SOCKET, SO_SNDBUF, &sendbuf_len, sizeof(int));

    最后通过直接修改系统的TCP发送缓冲区解决

    1. /proc/sys/net/core/rmem_max #收缓冲区最大值
    2. /proc/sys/net/core/wmem_max #发缓冲区最大值
    3. /proc/sys/net/core/rmem_default #收缓冲区默认值
    4. /proc/sys/net/core/wmen_default #发缓冲区默认值
    5. 1.一次能send的最大数据是发送缓冲区最大值的两倍(x2)
    6. 2.默认发送缓冲区最大值默认是(160 * 1024)
    7. 所以这里一次能发送的最大数据就是(320 * 1024)
    8. 3.观察应用层,发现发送的最大数据大小是 (450 * 1024)
    9. 所以这里设置发送缓冲区最大值为 (320 * 1024 = )
    10. echo 327680 > /proc/sys/net/core/wmem_max

    三、设置tcp的keepalive属性

    接收阻塞的问题还没有解决,最后发现通过设置tcp的keepalive属性能解决网络断开以后,接收阻塞不退出问题。

    1. int keepalive = 1; // 开启keepalive属性
    2. int keepidle = 10; // 如该连接在10秒内没有任何数据往来,则进行探测
    3. int keepinterval = 3; // 探测时发包的时间间隔为3秒
    4. int keepcount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.
    5. setsockopt(newsockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(keepalive));
    6. setsockopt(newsockfd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepidle, sizeof(keepidle));
    7. setsockopt(newsockfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval, sizeof(keepinterval));
    8. setsockopt(newsockfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount, sizeof(keepcount));

  • 相关阅读:
    Mac 安装软件各种报错解决方案
    【计算机网络系列】概述:计算机网络体系结构与参考模型
    XML-Based Configuration Beans for Ioc Container
    程序员8年薪资变化火了,网友直呼:我一年的和人家一个月差不多
    SSM整合
    AUTOSAR汽车电子嵌入式编程精讲300篇-汽车 CAN FD 总线应用研究
    css背景图片不影响上一层透明组件的背景色
    PHP传输base64数据不完整解决方法
    【教3妹学算法-每日3题(2)】通过翻转子数组使两个数组相等
    k8s 裸金属集群部署metalLB软负载均衡 —— 筑梦之路
  • 原文地址:https://blog.csdn.net/zengyaowu1988/article/details/125521169