Polling using Select function in C++ on Windows

偶尔善良 提交于 2020-07-22 09:16:21

问题


I am new in Socket Programming. I am trying to create a Application that uses Sockets for Communication.

I have doubt in the Receive function because sometime it just hangs in recvfrom function. I am using select function for polling. It works when Camera is connected but If I remove Camera it doesn't show the Error Message.

My Code for Polling:

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;
        }
     }
}

An one more question is that when I continously printing the Data Received Statement after sometime It stop. So how can I increase the size of Socket Receiving Buffer.

Thanks in Advance

Edit

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

回答1:


If you read select()'s documentation, you would see that select() returns -1 on error, 0 on timeout, and > 0 on requested event(s). However, that is not how you are treating the return value. You are treating -1 as timeout and >= 0 as data events. So, you end up calling recvfrom() when there is nothing available to read. If the socket is in blocking mode (its default mode), recvfrom() will block the calling thread until data is actually available.

Try this instead:

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;
}

As for the size of the socket's receive buffer, you can set it via setsockopt() using the SO_RCVBUF option, eg:

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


来源:https://stackoverflow.com/questions/51854161/polling-using-select-function-in-c-on-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!