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,表示当前没有数据可读取。
优点:非阻塞模式避免了等待时间过长的问题,并且能够更加灵活地处理数据包的接收。
缺点:需要额外的代码实现来避免在无数据时的过度循环,并且对于网络状况不佳的情况,可能会导致数据丢失。