在 Windows 上使用 C++ 中的 Select 函数进行轮询

Polling using Select function in C++ on Windows

我是 Socket Programming 的新人。我正在尝试创建一个使用 Sockets 进行通信的应用程序。

我对 Receive 函数有疑问,因为有时它只是挂在 recvfrom 函数中。 我正在使用 select 函数进行轮询。它在连接相机时有效,但如果我移除相机,它不会显示错误消息。

我的投票代码:

FD_ZERO(&m_readFds);
FD_SET(Sock, &m_readFds);

m_timeInterval.tv_usec = 30;            //30 Microseconds for Polling
m_socketLength = sizeof(m_cameraInfo);

m_lastBlockId = -1;

while (m_acquiringThreadStatus)
{
    FD_CLR(Sock, &m_readFds);
    FD_SET(Sock, &m_readFds);

    m_receivingStatus = select(Sock + 1, &m_readFds, NULL, NULL, &m_timeInterval);
    if (m_receivingStatus < 0)
    {
        std::cout << "No Data to Receive"<<std::endl;
    }
    else
    {
        if ((m_receivedBytes = recvfrom(Sock, m_packetBuffer, RECEIVING_BUFFER_SIZE, 0, (struct sockaddr*)&m_cameraInfo, &m_socketLength)) == SOCKET_ERROR)
        {
            std::cout << "ERROR" << std::endl;
        }
        else
        {
            std::cout<<"Data Received"<<std::endl;
        }
     }
}

还有一个问题是,当我在一段时间后连续打印 Data Received 语句时,它停止了。那么如何增加 Socket Receiving Buffer.

的大小

提前致谢

编辑

SOCKET m_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(m_sock == INVALID_SOCKET)
{
// Error
}
else
{
//In the else part bind the socket 
}

如果您阅读 select() 的文档,您会看到 select() returns -1 表示错误,0 表示超时,> 0 表示请求的事件.但是,这不是您处理 return 值的方式。您将 -1 视为超时,将 >= 0 视为数据事件。因此,当没有任何内容可供阅读时,您最终会调用 recvfrom()。如果套接字处于阻塞模式(默认模式),recvfrom() 将阻塞调用线程,直到数据实际可用。

试试这个:

m_lastBlockId = -1;

while (m_acquiringThreadStatus)
{
    FD_ZERO(&m_readFds);
    FD_SET(Sock, &m_readFds);

    m_timeInterval.tv_sec = 0;
    m_timeInterval.tv_usec = 30; //30 Microseconds for Polling

    m_receivingStatus = select(Sock + 1, &m_readFds, NULL, NULL, &m_timeInterval);

    if (m_receivingStatus == SOCKET_ERROR)
    {
        std::cout << "ERROR" << std::endl;
        break;
    }

    if (m_receivingStatus == 0)
    {
        std::cout << "No Data to Receive" << std::endl;
        continue;
    }

    m_socketLength = sizeof(m_cameraInfo);
    if ((m_receivedBytes = recvfrom(Sock, m_packetBuffer, RECEIVING_BUFFER_SIZE, 0, (struct sockaddr*)&m_cameraInfo, &m_socketLength)) == SOCKET_ERROR)
    {
        std::cout << "ERROR" << std::endl;
        break;
    }

    std::cout << "Data Received" << std::endl;
}

关于套接字接收缓冲区的大小,您可以通过setsockopt()使用SO_RCVBUF选项来设置它,例如:

int bufsize = ...;
setsockopt(Sock, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, sizeof(bufsize));