Reputation: 3
Here is my situation, I am using UDP, and have a server who is sending me data, but he could also possibly not send the data, due to a lost packet, and I'd like him to resend it, but my client might also not receive the data, so I'd like him re-read it. For now, I decided to go with a timeout on my client, who will wait a certain amount of time, and then re-read. My problem is that, is simply adding a goto which heads back to the select going to solve the issue, or will select be broken after the first timeout? Do I havet to make the socket non-blocking? I read that somewhere on the net. Essentially, my goal is that if read doesn't happen, try again, after a certain period of time, cause I know thes sender is trying to send. I want to know if my logic is correct since there is no way of me testing it.
fd_set set;
struct timeval timeout;
int rv;
char buff[100];
int len = 100;
FD_ZERO(&set); /* clear the set */
FD_SET(sockfd, &set); /* add our file descriptor to the set */
timeout.tv_sec = 0;
timeout.tv_usec = 10000;
retry:
write(sockfd,"hi",3);//sent to client now waiting for an ack
rv = select(sockfd + 1, &set, NULL, NULL, &timeout);
read(sockfd, buff, strlen(buff), 0);
if(rv == -1)
perror("select"); /* an error accured */
else if(rv == 0)
printf("timeout");
goto retry;
else
read( filedesc, buff, len ); /* there was data to read */
}
Upvotes: 0
Views: 746
Reputation: 10396
I would excpect that select modifies your fd_set so that it doesn't contain your sockfd anymore after read (because it wasn't ready to read). So just to be sure you should reinitialize the set before the retry. Or you could try if the fd is still there after a timeout, but I think the normal behaviour is to reinitialize all FDs before calling select. If you use poll or epoll you don't have to do that.
Apart from that the code looks ok.
Whether you use blockin or nonblocking IO doesn't matter for the read in your case. If you use non-blocking your write could fail, therefore staying with blocking is easier.
Upvotes: 1