错误编号: 11,资源暂时不可用。

21

我正在使用C语言sockets实现可靠的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()和非阻塞套接字。 select()方法更加灵活、可靠和可移植。 - Michael Shmalko
第二个代码片段中没有调用recvfrom() - alk
recvfrom() 返回的是 ssize_t 而不是 int,顺便说一下。 - alk
2个回答

27
当使用setsockopt()设置超时时间并在阻塞套接字上调用recvfrom()时,如果recvfrom()调用超时(即:在指定的超时时间内没有收到数据),通常会出现错误EAGAIN(11)
man recvfrom中直接引用:

返回值

...

错误

...

EAGAIN或EWOULDBLOCK 套接字已标记为非阻塞模式,并且接收操作将阻塞,或者已经设置了接收超时时间,超时时间已经到期但未接收到数据。...

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

2

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接