Linux 非阻塞方式Send函数报“Resource temporarily unavailable“优化方法

这篇具有很好参考价值的文章主要介绍了Linux 非阻塞方式Send函数报“Resource temporarily unavailable“优化方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

linux下将Send发送函数设置为非阻塞方式【如,send(socket, data + (dataLen - leftLen), leftLen, MSG_DONTWAIT)】,然后使用send向服务器发送大量数据(如图片,上百k数据);

非阻塞方式含义:就是将待发送数据拷贝到底层协议栈缓存区,不需要对端确认数据已接收。如果缓存区可用空间够或者不够,返回成功拷贝的大小。如缓存区可用空间为0,则返回-1,同时错误码errno为EAGAIN(含义为再次尝试),错误原因为Resource temporarily unavailable。

背景:

项目中会向服务器上报图片等大量数据,因底层协议buf缓存小(小于需要上报的数据),使用非阻塞Send函数的数据正常上报时也会出现资源不可用"Resource temporarily unavailable"的正常现象;

当网络异常时,底层buf被沾满后无法释放导致一直出现资源不可用的错误,但此时又无法检测到TCP链接断开,会引起代码一直阻塞在数据上报流程中无法退出

/********检测TCP链接是否断开***********/
long checkTcpConn(long socket)
{
    long lRet = 0;
    struct tcp_info info;
    int optlen = sizeof(struct tcp_info);
    lRet = getsockopt(Socket, IPPROTO_TCP,TCP_INFO, &info, (socklen_t *)&optlen);
    if (lRet < 0  || info.tcpi_state != TCP_ESTABLISHED)
    {
        //Tcp链接已断开
        return -1;
    }
     return 0;
}

优化方法:超时退出

记录大量数据正常上报完成时,出现资源不可用"Resource temporarily unavailable"的时长 normalTime => 根据时间来区分是否链接异常,进而可及时退出数据上报流程避免阻塞;

long sendDataToServer(long dataLen, char *data)
{
    long leftLen = dataLen;
    long sendLen = 0;
    long curTime = 0;
    long lastSendFailTime = 0;
    #define SEND_FAIL_TIMEOUT_THR (3)    //大于上述的normalTime
    
    while(leftLen > 0)
    {
        sendLen = send(socket, data + (dataLen - leftLen), leftLen, MSG_DONTWAIT);
    
        if(sendLen <= 0)
        {
            if(errno != EAGAIN && (errno != WSAEWOULDBLOCK) && errno != EINTR)  
            {    
                printf("send data fail, error[%s]", strerror(errno));
                return -1;
            }  
    
            if(-1 == checkTcpConn(socket))
            {
                //检测到TCP链接断开
                return -1;
            }
    
            if(errno == EAGAIN)
            {
                //获取当前时间,单位s
                curTime = getUtcTime();
                if(0 == lastSendFailTime)
                {        
                    lastSendFailTime = curTime;
                }
                else if(curTime - lastSendFailTime >= SEND_FAIL_TIMEOUT_THR)
                {
                    //认为 TCP链接断开,退出循环
                    return -1;
                }
            }
        }
        else
        {
            leftLen -= sendLen;
        } 
    }
    return 0;
}

附,参考文档链接:

https://blog.csdn.net/xclshwd/article/details/102985388

https://www.jianshu.com/p/7ecd6a5530ce文章来源地址https://www.toymoban.com/news/detail-661317.html

到了这里,关于Linux 非阻塞方式Send函数报“Resource temporarily unavailable“优化方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux】进程信号——进程信号的概念和介绍、产生信号、四种产生信号方式、阻塞信号、捕捉信号、阻塞和捕捉信号的函数

      在Linux中,进程信号是一种异步的事件通知机制,用于通知进程某个事件已经发生。它是进程间通信的一种方式,可以用来控制进程的行为。   当一个进程收到信号时,操作系统会中断该进程的正常控制流程,并执行相应的处理函数。进程收到信号后有三种处理方式:

    2024年02月02日
    浏览(55)
  • linux C语言socket函数send

    在Linux中,使用C语言进行网络编程时, send 函数是用于发送数据到已连接的套接字的重要函数 之一。它通常用于TCP连接,但也可以用于UDP(尽管对于UDP,通常更推荐使用 sendto ,因为它允许你指定目标地址和端口)。 下面是 send 函数的详细解释: recv  函数在  sys/socket.h  中

    2024年02月20日
    浏览(31)
  • MPI之MPI_Send&MPI_Recv阻塞接口及参数详解

    MPI简介以及阻塞非阻塞代码示例 MPI_Send buf:指向发送缓冲区的指针; count:发出的消息的数量(例如,整数个数、字节数等); datatype:发出消息的数据类型。MPI 数据类型通常是针对特定的数据结构(如 char、int、float 等)定义的,它仅能在使用相同 MPI_Datatype 的进程间传递

    2024年02月11日
    浏览(41)
  • 安装或者卸载软件时遇到trying to use is on a network resource that is unavailable

    The feature you are trying to use is on a network resource is unavailable 点击ok之后会有Click OK to try again, or enter an alternate path to afolder containing the installation package \\\'EndNote x9v19.0.0.12062 Setup(1).msi\\\' in the box below. 具体如下图所示: 博主花费一早上的时间终于解决这个问题,主要是由于 您试图使用的

    2024年02月07日
    浏览(219)
  • Linux——信号处理函数与阻塞状态的进程

    这篇博客记录一下我在编写一个简单的多进程回声服务器的时候出现的问题。 这个问题就在于忽略了几个有关于信号处理函数的基本常识: 用通俗的话讲信号注册函数(signal、sigaction)的功能:进程告诉操作系统,当以后收到向信号注册函数传入的信号时,你帮我调用一下信号

    2024年02月13日
    浏览(38)
  • socket send函数系列,彻底弄懂socket发送函数,可做参考手册

    目录 1.系统调用流程 2 发送函数系列 2.1 send函数 2.2 sendto函数 2.3 sendmsg函数 2.4 write函数 2.5 writev函数 图 1 2.1 send函数 send函数为套接字发送函数,需套接字进行connect操作才能使用。 2.2 sendto函数 sendto函数为套接字发送函数,不管套接字是否进行connect操作都能使用。 未connect:

    2024年02月07日
    浏览(45)
  • Python 中 Selenium 的 send_keys() 函数

    我们将介绍 Selenium Python 中的 send_keys() 函数并演示其用法。 任何应用程序在进入市场之前都需要经过一些测试。 应用程序应首先满足与其名称相关的所有要求。 我们应该全面测试应用程序,因为没有人能够预测给予应用程序的确切输入。 Python Selenium 可以帮助我们测试所有

    2024年02月03日
    浏览(30)
  • c++ socket、 listen、accept、recv 、send、 connect函数记录

    __domain为协议域,又称协议族,我们最常用的有AF_INET、AF_INET6(也可以写作为PF_INET、PF_INET6),分别代表IPv4地址和IPv6地址。 __type为数据传输方式或套接字类型,最常见的有SOCK_STREAM和 SOCK_DGRAM,其中SOCK_STREAM为面向连接的数据传输方式,是基于TCP的协议,数据可以准确无误地

    2023年04月26日
    浏览(32)
  • ARM 循环阻塞延迟函数

         串行驱动的关键是双方能够按照既定的时序进行检测、设置相关引脚上的电平,比如单总线、I2c这样基本的可以用GPIO模拟的时序协议,需要主从双方,必须在链路接口内严格按照微妙级的延迟单位进行时序同步。 所以,在这种对时间要求很敏感的情况下,一般都会考虑

    2024年02月15日
    浏览(33)
  • Android Glide同步阻塞方式submit获得Bitmap,kotlin

    droid Glide同步阻塞方式submit获得Bitmap,kotlin     需要放入后台线程,不能在主线程。   Android Glide预加载preload ,kotlin_zhangphil的博客-CSDN博客 【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬而未决:比如用户的头像,往

    2024年02月16日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包