【问题标题】:sendto : Resource temporarily unavailable (errno 11)sendto : 资源暂时不可用 (errno 11)
【发布时间】:2011-08-09 21:33:42
【问题描述】:

我遇到了 sendto 的问题。

我有一个接收者使用 recvfrom 接收 UPD 数据包,然后使用 sendto 回复发送者。

不幸的是,我收到 errno 11(资源暂时不可用)。我正在使用两个套接字。

第一个数据包实际上是发送的,但不是后面的:

发送到 :: 成功

错误:0。

sendto :: 资源暂时不可用

错误:11。

sendto :: 资源暂时不可用

...

这是我的代码的摘录:

    int sockfd, sockSend;

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
            perror("socket");

    if ((sockSend = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
            perror("socket");

    if (fcntl(sockfd, F_SETOWN, getpid()) < 0) {
            perror("fcntl"); 
    }
    if (fcntl(sockfd, F_SETFL, O_RDONLY | O_NONBLOCK | FASYNC) < 0) {
            perror("fcntl"); 
    } 

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))
                    < 0)
            perror("bind");

在 SIGIO 处理程序中:

    len = sizeof(recv_addr);
    char buffer[payload];
    bzero(buffer, payload);
    n = recvfrom(sockfd, buffer, payload, MSG_DONTWAIT, (struct sockaddr *)&recv_addr, &len);

    while (n > 0) {

                            sprintf(response, "%d\n%d\n%d\n", items, target_buf, pb_sp);          
                            sendto(sockSend, response, strlen(response), 0, (struct sockaddr *) &recv_addr, sizeof(recv_addr));
                            // sleep(1);

                            perror("sendto :");
                            printf("error: %d.\n", errno);

     }

这个问题会不会是因为端口仍然很热,我需要等待才能重用它?我尝试更改端口,但没有帮助。

更新:如果 sleep(1) 被注释掉,那么数据包实际上会被发送!

非常感谢您的帮助。

【问题讨论】:

  • 您是否使用两个具有相同端口的套​​接字?如果有,原因是什么?
  • 也许SO_REUSEADDR 会有所帮助。或者你可以只保持端口打开而不是打开和关闭它,或者如果可行的话,每次都使用一个新的随机分配的端口号。
  • 我添加了更多代码。我有 2 个套接字,但只有一个绑定到一个端口(在特定端口上接收数据),另一个可以从任何端口发送数据。
  • R:我只是尝试使用 SO_REUSEADDR,但没有帮助。假设端口是什么意思?我不认为它正在关闭,因为我没有调用 close()?
  • 我意识到使用 sleep() 可以解决问题,但如果没有它,我不确定如何解决问题。

标签: c sockets udp sendto


【解决方案1】:

你得到的错误:

EAGAIN 或 EWOULDBLOCK:套接字标记为非阻塞,请求的操作将阻塞。 POSIX.1-2001 允许在这种情况下返回任一错误,并且不要求这些常量具有相同的值,因此可移植应用程序应检查这两种可能性。

您将套接字设置为非阻塞 (O_NONBLOCK)。套接字仍在忙于发送上一条消息。在第一个完成发送之前,您不能发送另一个。这就是睡眠有帮助的原因。

不要将其设置为非阻塞,或在select 表示可以后重试。

【讨论】:

  • 非常感谢。但是 O_NONBLOCK 用于 sockfd,sockSend 不应该阻塞(默认行为)吗?我使用 sockfd 接收和 sockSend 发送数据。我在 fcntl() 中删除了 O_NONBLOCK 并且发生了相同的行为。这就是你所说的,对吧?
  • 通过删除 O_NONBLOCK 和 MSG_DONTWAIT 它最终工作!非常非常感谢你!有什么办法可以保持一个套接字阻塞(发送)和一个非阻塞(接收)吗?!
【解决方案2】:

如果您必须将套接字设置为非阻塞,您可以使用select 安全地(并且仅?)完成它:

select()pselect() 允许程序监视多个文件描述符,等到一个或多个文件描述符“准备好”用于某种类型的I/O 操作(例如,可以输入)。如果可以在不阻塞的情况下执行相应的 I/O 操作(例如 read(2)),则认为文件描述符已准备就绪。

【讨论】:

    猜你喜欢
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多