2011-04-20 234 views
4

我遇到sendto问题。sendto:资源暂时不可用(errno 11)

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

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

第一个数据包实际发送,但不是那些算账:

SENDTO ::成功

错误: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); 

    } 

难道这个问题来,因为港口仍然是热的,我需要等待重用之前?我试图改变港口,但它没有帮助。

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

非常感谢您的帮助。

+0

您使用的两个插槽具有相同的端口?如果是这样,原因是什么? – penguin359 2011-04-20 22:47:36

+0

也许'SO_REUSEADDR'会有所帮助。或者您可以保持端口开放而不是打开和关闭端口,或者每次都可以使用新的随机分配的端口号。 – 2011-04-20 22:52:02

+0

我已添加更多代码。我有2个套接字,但只有一个绑定到一个端口(接收特定端口上的数据),另一个可以从任何端口发送数据。 – Jary 2011-04-20 22:53:31

回答

8

你所得到的错误:

EAGAIN or EWOULDBLOCK: The socket is marked nonblocking and the requested operation would block. POSIX.1-2001 allows either error to be returned for this case, and does not require these constants to have the same value, so a portable application should check for both possibilities.

您的插座设置为非阻塞(O_NONBLOCK)。套接字仍然忙于发送前一条消息。直到第一个完成发送,您才能发送另一个。这就是为什么睡眠有帮助。

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

+0

非常感谢。但O_NONBLOCK用于sockfd,不应该被sockSend阻塞(默认行为)?我使用sockfd接收和sockSend发送数据。我删除了fcntl()中的O_NONBLOCK,并发生相同的行为。这就是你提到的,对吧? – Jary 2011-04-21 00:17:59

+0

通过删除O_NONBLOCK和MSG_DONTWAIT,它结束了工作!非常非常感谢你!有没有办法阻止一个套接字(发送)和一个非阻塞(用于接收)? – Jary 2011-04-21 00:51:25

0

如果你必须设置套接字非阻塞,你可以放心地使用select做到这一点(只有):

select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible). A file descriptor is considered ready if it is possible to perform the corresponding I/O operation (e.g., read(2)) without blocking.

相关问题