问题
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