唐宋元明沁清 2023-06-13 17:14 采纳率: 56%
浏览 21
已结题

windows下udp的recvfrom函数设置超时没法退出?

windows下udp的recvfrom函数设置超时没法退出?

struct timeval tv_out;
tv_out.tv_sec = 0;//这里改为1s下面设置为0,可以正常退出,但是超时时间为1s感觉太长了
tv_out.tv_usec = RECVTIMEOUT;//这里时间设置多少都没生效,退出时还是卡在recvfrom函数
if(setsockopt(m_nRecvSockFd, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv_out, sizeof(tv_out)) == -1)
{
    //qDebug(QString("设置超时 failed %1").arg(WSAGetLastError()));
#ifdef  _WIN32
    closesocket(pSocketFd);
#elif linux
    close(pSocketFd);
#elif unix // all unices not caught above
    close(pSocketFd);
#else
# error "Unknown"
#endif
    return false;
}

有朋友做过类似的项目吗?提供一点经验,之所以用阻塞的方式原因如下(优点:减少丢包):

阻塞模式
在阻塞模式下,程序调用recvfrom函数后会一直等待,直到有数据可读取。recvfrom函数会一直阻塞,直到读取到至少一个数据包为止。如果没有数据可读取,函数会等待直到超时或者数据到达。

优点:阻塞模式能够确保接收所有的数据包,并且对于网络状况不稳定的情况下,可以保证数据的正常获取。

缺点:在没有数据到达时,该方式可能会浪费较多的资源。

非阻塞模式
在非阻塞模式下,recvfrom函数会立即返回。如果有数据可读取,函数返回读取到的字节数。否则,函数会返回错误代码EAGAIN或EWOULDBLOCK,表示当前没有数据可读取。

优点:非阻塞模式避免了等待时间过长的问题,并且能够更加灵活地处理数据包的接收。

缺点:需要额外的代码实现来避免在无数据时的过度循环,并且对于网络状况不佳的情况,可能会导致数据丢失。

  • 写回答

1条回答 默认 最新

  • 憧憬blog 2023-06-13 17:44
    关注

    Windows下使用UDP的recvfrom函数设置超时时,如果recvfrom函数没有接收到数据,会阻塞等待直到超时或者数据到达。如果您设置的超时时间过长,可能会导致程序一直等待,无法退出。

    解决这个问题的方法是,使用Windows下提供的另外一个函数来实现超时功能,例如:

    int nRecvSize = 0;
    fd_set fdRead;
    FD_ZERO(&fdRead);
    FD_SET(m_nRecvSockFd, &fdRead);
    timeval timeout = {0, RECVTIMEOUT}; // 设置超时时间
    int nRet = select(m_nRecvSockFd + 1, &fdRead, NULL, NULL, &timeout);
    if (nRet < 0) {
        // select 函数调用失败
        return false;
    } else if (nRet == 0) {
        // 超时
        return false;
    } else {
        // 有数据可读取
        nRecvSize = recvfrom(m_nRecvSockFd, ...);
        ...
    }
    

    这里使用了Windows下的select函数来实现超时功能。首先,将UDP套接字加入到fdRead集合中,然后调用select函数等待数据到达或者超时。如果select函数返回0,表示超时;如果返回-1,表示调用失败;如果返回大于0,表示有数据可读取,此时调用recvfrom函数来接收数据。

    另外,您提到使用阻塞模式来接收UDP数据能够减少丢包,这是因为阻塞模式能够确保接收所有的数据包,但是会浪费较多的资源。如果您的应用程序需要处理高并发的UDP数据,建议使用非阻塞模式来处理,以提高系统的性能和稳定性。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 6月22日
  • 已采纳回答 6月14日
  • 创建了问题 6月13日

悬赏问题

  • ¥20 python忆阻器数字识别
  • ¥15 无法输出helloworld
  • ¥15 高通uboot 打印ubi init err 22
  • ¥20 PDF元数据中的XMP媒体管理属性
  • ¥15 R语言中lasso回归报错
  • ¥15 网站突然不能访问了,上午还好好的
  • ¥15 有没有dl可以帮弄”我去图书馆”秒选道具和积分
  • ¥15 semrush,SEO,内嵌网站,api
  • ¥15 Stata:为什么reghdfe后的因变量没有被发现识别啊
  • ¥15 振荡电路,ADS仿真