在 Windows 上使用 C++ 中的 Select 函数进行轮询 [英] Polling using Select function in C++ on Windows
问题描述
我是套接字编程
的新手.我正在尝试创建一个使用 Sockets
进行通信的应用程序.
I am new in Socket Programming
. I am trying to create a Application that uses Sockets
for Communication.
我对 Receive 函数有疑问,因为有时它只是挂在 recvfrom
函数中.我正在使用 select
函数进行轮询.它在连接相机时工作,但如果我移除相机,它不会显示错误消息.
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.
我的投票代码:
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
.
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
.
提前致谢
编辑
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()
返回 -错误为 1,超时为 0,请求的事件为 > 0.但是,这不是您处理返回值的方式.您将 -1 视为超时,将 >= 0 视为数据事件.因此,当没有任何内容可供读取时,您最终会调用 recvfrom()
.如果套接字处于阻塞模式(其默认模式),recvfrom()
将阻塞调用线程,直到数据实际可用.
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.
试试这个:
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;
}
关于socket接收缓冲区的大小,可以通过setsockopt()
使用SO_RCVBUF
选项来设置,例如:
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));
这篇关于在 Windows 上使用 C++ 中的 Select 函数进行轮询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!