问题
Hi I'm creating a proxyserver that wait for packets from client with an UDP connection and checks if all of them are effectively arrived or same of them have been rejected .
In that case I should send an "ack" to the clients for each lost packet (with send_ack() ) but just after have sent the first ack the "if part" of the select loops sending unlimited acks never going back to the "else part" were the select listen data from client (receive _pkt() function )
fd_set rset, allset;
int maxfd, nready;
struct timeval timeout;
timeout.tv_sec = 4;
timeout.tv_usec = 150000;
maxfd = socketfd;
FD_ZERO(&allset);
FD_SET(socketfd, &allset);
rset = allset;
for( i=0; ;i++){
do {
nready=select( (maxfd +1), &rset, NULL, NULL, &timeout);
} while ((nready<0) & (errno==EINTR));
if( nready<0) {
perror("Error main: select failed: ");
exit(32);
}
if( nready==0){
send_ack(socketfd,head);
}
else{
receive_pkt(socketfd, head);
}
}
Hope it's enough clear, thanks for the advices!
回答1:
On some systems (Linux in particular), a select
call modifies the timeout to show how much time is left. So in your case, if it waits 3 seconds for a packet, timeout will be reduced to 1.15 seconds, and after a total of 4.15 seconds, timeout will be 0, so later calls to select
will immediately return with nready == 0.
If you want to wait again after sending an ack, you need to reset the timeout to non-zero.
回答2:
One has to reset the fd_set rset
before every call to select
. The select
call expects a bit set of field descriptors to monitor and overwrites with a bit set of field descriptors with notifications to read.
for( i=0; ;i++){
do {
rset = allset;
nready=select( (maxfd +1), &rset, NULL, NULL, &timeout);
} while ((nready<0) & (errno==EINTR));
来源:https://stackoverflow.com/questions/15480599/udp-sockets-use-of-select