UDP套接字使用select()

嗨,我正在创建一个代理服务器,等待来自客户端的数据包与UDP连接,并检查是否所有这些都是有效到达或相同的已被拒绝。

在这种情况下,我应该为每个丢失的数据包(使用send_ack())向客户端发送“确认”,但在发送了第一个确认之后,发送无限制的选择循环的“if部分”永远不会返回到“其他”部分“是来自客户端的选择监听数据(接收_pkt()函数)

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); } } 

希望它足够清楚,谢谢你的建议!

在某些系统(特别是Linux)上, select调用会修改超时以显示剩余时间。 因此,在您的情况下,如果数据包等待3秒,超时将减少到1.15秒,并且总共4.15秒后,超时将为0,因此稍后调用select将立即返回nready == 0。

如果要在发送确认后再次等待,则需要将超时重置为非零。

必须在每次调用select之前重置fd_set rsetselect调用需要一组字段描述符来监视和覆盖一组字段描述符以及要读取的通知。

 for( i=0; ;i++){ do { rset = allset; nready=select( (maxfd +1), &rset, NULL, NULL, &timeout); } while ((nready<0) & (errno==EINTR));