在 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));
我是 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));