【问题标题】:UDP sockets use of select()UDP 套接字使用 select()
【发布时间】:2013-03-18 15:30:20
【问题描述】:

您好,我正在创建一个代理服务器,它通过 UDP 连接等待来自客户端的数据包,并检查它们是否全部有效到达或是否相同。

在这种情况下,我应该为每个丢失的数据包(使用 send_ack() )向客户端发送一个“ack”,但在发送第一个 ack 之后,选择循环的“if 部分”发送无限的 ack 永远不会返回“其他部分”是来自客户端的选择监听数据(接收 _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);
    }
}

希望够清楚,谢谢指教!

【问题讨论】:

  • 您的实际问题是什么?
  • 我怎样才能取消这个循环?:“在发送第一个确认之后,选择循环的“if 部分”发送无限的确认并且永远不会回到“else 部分”是选择监听来自客户端的数据(接收 _pkt() 函数)"

标签: c sockets multiplexing


【解决方案1】:

在某些系统(尤其是 Linux)上,select 调用会修改超时以显示剩余时间。所以在你的情况下,如果它等待一个数据包 3 秒,超时将减少到 1.15 秒,总共 4.15 秒后,超时将为 0,所以稍后对 select 的调用将立即返回 nready == 0 .

如果你想在发送 ack 后再次等待,你需要将超时重置为非零。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      • 2020-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多