У меня небольшая проблема с сокетами, когда я не получаю данные, за исключением первого цикла, это время от времени. Если я закрываю и снова открываю сокет каждый цикл, хотя я, кажется, правильно получаю данные. Есть идеи о том, почему?linux C++ socket select loop
Пример цикла без закрытия:
int socketHandle = socket(AF_INET,SOCK_DGRAM,0);
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(/*UDP IP ADDRESS*/);
serverAddr.sin_port = htons(/*UDP PORT*/);
struct timeval tv;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(socketHandle, &rfds);
tv.tv_usec = 0.0;
int recVal = 0;
int sockLen = sizeof(serverAddr);
bind(socketHandle, (struct sockaddr*)&serverAddr, (socklen_t)sockLen);
bool timePassed = false;
time_t startListenTime = time(NULL);
tv.tv_sec = maxUpdateTime;
while(true)
{
recVal = select(socketHandle + 1, &rfds, NULL, NULL, &tv);
switch(recVal)
{
case(0):
{
//Timeout
break;
}
case(-1):
{
//Error
break;
}
default:
{
/*Packet Data Type*/ pkt;
if(recvfrom(socketHandle, &pkt, sizeof(/*Packet Data Type*/), 0, (sockaddr*)&serverAddr, (socklen_t*)&sockLen) < 0)
{
//Failed to Recieve Data
break;
}
else
{
//Recieved Data!!
}
break;
}
}
}
Пример цикла с закрытием:
while(true)
{
int socketHandle = socket(AF_INET,SOCK_DGRAM,0);
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(/*UDP IP ADDRESS*/);
serverAddr.sin_port = htons(/*UDP PORT*/);
struct timeval tv;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(socketHandle, &rfds);
tv.tv_usec = 0.0;
int recVal = 0;
int sockLen = sizeof(serverAddr);
bind(socketHandle, (struct sockaddr*)&serverAddr, (socklen_t)sockLen);
bool timePassed = false;
time_t startListenTime = time(NULL);
tv.tv_sec = maxUpdateTime;
recVal = select(socketHandle + 1, &rfds, NULL, NULL, &tv);
switch(recVal)
{
case(0):
{
//Timeout
break;
}
case(-1):
{
//Error
break;
}
default:
{
/*Packet Datastructure*/ pkt;
if(recvfrom(socketHandle, &pkt, sizeof(/*Packet Datastructure*/), 0, (sockaddr*)&serverAddr, (socklen_t*)&sockLen) < 0)
{
//Failed to read packet
break;
}
else
{
//Read Packet!!
}
break;
}
}
close(socketHandle);
}
переместите FD_ZERO() и FD_SET() внутри цикла прямо относительно select(). –
См. Это http://www.mkssoftware.com/docs/man3/select.3.asp, говорящие, что дескрипторы изменены, чтобы показать, какие дескрипторы готовы для ввода-вывода. –
@RichardChambers, вы должны сделать ответ не просто комментарием, поэтому я могу его продвинуть :) –