18

我正在使用 c 套接字来实现可靠的 UDP 协议。我正在使用以下代码在等待确认的套接字上设置超时。我不知道为什么我得到 errno 11,资源暂时不可用。

        //set timer for recv_socket
        struct timeval tv;
        tv.tv_usec = TIMEOUT_MS;

        if(setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0){
            printf("Error setting the socket timeout.\n");
        }

        int recv_msg_len;
        if(recv_msg_len = recvfrom(rcv_sock, ackBuffer,sizeof(ackBuffer), 0,
               (struct sockaddr *) &servAddr2, &fromSize) < 0){
            //timeout reached
            printf("Error Reporting: %d : %s\n", errno, strerror(errno));
            num_timeouts++;
        }

我也尝试了评论中提到的 select 方法。我在循环中有以下代码,但 recvfrom 永远不会超时。

        fd_set set;
        FD_ZERO(&set);      /* empties the set */
        FD_CLR(rcv_sock,&set);    /* removes FD from the set */
        FD_SET(rcv_sock,&set);    /* adds FD to the set */

        if(select(rcv_sock + 1, &set, NULL, NULL, &tv) < 0){
            printf("\nError Reporting: %d : %s\n\n", errno, strerror(errno));
            return -1;
        }


        if(!FD_ISSET(rcv_sock,&set)){   /* true if FD is in the set */
            printf("socket is not set properly.\n");
        }
4

2 回答 2

23

当调用recvfrom()阻塞套接字并设置了超时时,如果调用超时(即:在指定为超时的时间段内没有收到数据),setsockopt()通常会出现错误。EAGAIN (11)recvfrom()

逐字逐句man recvfrom

返回值

...

错误

... .

EAGAIN 或 EWOULDBLOCK 套接字被标记为非阻塞并且接收操作将阻塞,或者已设置接收超时并且在接收数据之前超时已过期。...

要解决这个问题:只需recvfrom ()再次调用...... ;-)

于 2012-11-26T11:05:29.503 回答
1

对我来说,问题是由于 ipV6 数据包到达绑定到特定端口的 UDP 套接字。这些触发了 select() 但是当我尝试使用 recvfrom() 读取它们时,调用返回“资源暂时不可用”。我的应用程序不需要 IPV6,所以我只是通过 sysctl.conf 禁用了它。问题现在消失了!

于 2015-05-05T19:03:04.723 回答